lok: Don't attempt to select the exact text after a failed search.
[LibreOffice.git] / svx / source / table / svdotable.cxx
bloba308c34f03debc0f3a999b30ac445592aaa1358a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
21 #include <com/sun/star/container/XNamed.hpp>
22 #include <com/sun/star/container/XNameAccess.hpp>
23 #include <com/sun/star/container/XIndexAccess.hpp>
25 #include <vcl/canvastools.hxx>
26 #include <com/sun/star/style/XStyle.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <basegfx/polygon/b2dpolygontools.hxx>
29 #include <basegfx/polygon/b2dpolypolygon.hxx>
30 #include <basegfx/polygon/b2dpolygon.hxx>
31 #include <svl/style.hxx>
32 #include "editeng/editstat.hxx"
33 #include "editeng/outlobj.hxx"
34 #include "svx/svdview.hxx"
35 #include "sdr/properties/textproperties.hxx"
36 #include "svx/svdotable.hxx"
37 #include "svx/svdhdl.hxx"
38 #include "viewcontactoftableobj.hxx"
39 #include "svx/svdoutl.hxx"
40 #include "svx/svddrag.hxx"
41 #include "svx/svdpagv.hxx"
42 #include "tablemodel.hxx"
43 #include "cell.hxx"
44 #include "svx/xflclit.hxx"
45 #include "tablelayouter.hxx"
46 #include "svx/svdetc.hxx"
47 #include "tablehandles.hxx"
48 #include "editeng/boxitem.hxx"
49 #include "svx/framelink.hxx"
50 #include "svx/sdr/table/tabledesign.hxx"
51 #include "svx/svdundo.hxx"
52 #include "svx/svdstr.hrc"
53 #include "svdglob.hxx"
54 #include "editeng/writingmodeitem.hxx"
55 #include "editeng/frmdiritem.hxx"
56 #include "svx/xflhtit.hxx"
57 #include "svx/xflftrit.hxx"
58 #include "svx/xfltrit.hxx"
62 using ::com::sun::star::uno::Any;
63 using ::com::sun::star::uno::Reference;
64 using ::com::sun::star::uno::XInterface;
65 using ::com::sun::star::uno::UNO_QUERY;
66 using ::com::sun::star::uno::UNO_QUERY_THROW;
67 using ::com::sun::star::uno::Exception;
68 using ::com::sun::star::container::XIndexAccess;
69 using ::com::sun::star::style::XStyle;
70 using ::com::sun::star::table::XTableRows;
71 using ::com::sun::star::table::XTableColumns;
72 using ::com::sun::star::table::XTable;
73 using ::com::sun::star::beans::XPropertySet;
74 using ::com::sun::star::util::XModifyBroadcaster;
75 using sdr::properties::TextProperties;
76 using sdr::properties::BaseProperties;
77 using namespace ::com::sun::star;
78 using namespace ::com::sun::star::text;
79 using namespace ::com::sun::star::container;
80 using namespace ::com::sun::star::style;
82 namespace sdr { namespace table {
84 class TableProperties : public TextProperties
86 protected:
87 // create a new itemset
88 SfxItemSet* CreateObjectSpecificItemSet(SfxItemPool& rPool) SAL_OVERRIDE;
90 public:
91 // basic constructor
92 TableProperties(SdrObject& rObj );
94 // constructor for copying, but using new object
95 TableProperties(const TableProperties& rProps, SdrObject& rObj );
97 // destructor
98 virtual ~TableProperties();
100 // Clone() operator, normally just calls the local copy constructor
101 BaseProperties& Clone(SdrObject& rObj) const SAL_OVERRIDE;
103 virtual void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem) SAL_OVERRIDE;
106 TableProperties::TableProperties(SdrObject& rObj)
107 : TextProperties(rObj)
111 TableProperties::TableProperties(const TableProperties& rProps, SdrObject& rObj)
112 : TextProperties(rProps, rObj)
116 TableProperties::~TableProperties()
120 BaseProperties& TableProperties::Clone(SdrObject& rObj) const
122 return *(new TableProperties(*this, rObj));
125 void TableProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
127 if( nWhich == SDRATTR_TEXTDIRECTION )
128 AttributeProperties::ItemChange( nWhich, pNewItem );
129 else
130 TextProperties::ItemChange( nWhich, pNewItem );
133 // create a new itemset
134 SfxItemSet* TableProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
136 return new SfxItemSet(rPool,
138 // range from SdrAttrObj
139 SDRATTR_START, SDRATTR_SHADOW_LAST,
140 SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST,
141 SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION,
143 // range for SdrTableObj
144 SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST,
146 // range from SdrTextObj
147 EE_ITEMS_START, EE_ITEMS_END,
149 // end
150 0, 0);
153 class TableObjectGeoData : public SdrTextObjGeoData
155 public:
156 Rectangle maLogicRect;
159 TableStyleSettings::TableStyleSettings()
160 : mbUseFirstRow(true)
161 , mbUseLastRow(false)
162 , mbUseFirstColumn(false)
163 , mbUseLastColumn(false)
164 , mbUseRowBanding(true)
165 , mbUseColumnBanding(false)
169 TableStyleSettings::TableStyleSettings( const TableStyleSettings& rStyle )
171 (*this) = rStyle;
174 TableStyleSettings& TableStyleSettings::operator=(const TableStyleSettings& rStyle)
176 mbUseFirstRow = rStyle.mbUseFirstRow;
177 mbUseLastRow = rStyle.mbUseLastRow;
178 mbUseFirstColumn = rStyle.mbUseFirstColumn;
179 mbUseLastColumn = rStyle.mbUseLastColumn;
180 mbUseRowBanding = rStyle.mbUseRowBanding;
181 mbUseColumnBanding = rStyle.mbUseColumnBanding;
182 return *this;
185 bool TableStyleSettings::operator==( const TableStyleSettings& rStyle ) const
187 return
188 (mbUseFirstRow == rStyle.mbUseFirstRow) &&
189 (mbUseLastRow == rStyle.mbUseLastRow) &&
190 (mbUseFirstColumn == rStyle.mbUseFirstColumn) &&
191 (mbUseLastColumn == rStyle.mbUseLastColumn) &&
192 (mbUseRowBanding == rStyle.mbUseRowBanding) &&
193 (mbUseColumnBanding == rStyle.mbUseColumnBanding);
198 class SdrTableObjImpl : public TableDesignUser, public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener >
200 public:
201 CellRef mxActiveCell;
202 TableModelRef mxTable;
203 SdrTableObj* mpTableObj;
204 TableLayouter* mpLayouter;
205 CellPos maEditPos;
206 TableStyleSettings maTableStyle;
207 Reference< XIndexAccess > mxTableStyle;
208 bool mbModifyPending;
210 void SetModel(SdrModel* pOldModel, SdrModel* pNewModel);
212 CellRef getCell( const CellPos& rPos ) const;
213 void LayoutTable( Rectangle& rArea, bool bFitWidth, bool bFitHeight );
215 bool ApplyCellStyles();
216 void UpdateCells( Rectangle& rArea );
218 SdrTableObjImpl();
219 virtual ~SdrTableObjImpl();
221 void init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows );
222 void dispose();
224 sal_Int32 getColumnCount() const;
225 sal_Int32 getRowCount() const;
227 void DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset );
229 SdrTableObjImpl& operator=( const SdrTableObjImpl& rSource );
231 // XModifyListener
232 virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
234 // XEventListener
235 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
237 void update();
239 void connectTableStyle();
240 void disconnectTableStyle();
241 virtual bool isInUse() SAL_OVERRIDE;
242 private:
243 static SdrTableObjImpl* lastLayoutTable;
244 static Rectangle lastLayoutInputRectangle;
245 static Rectangle lastLayoutResultRectangle;
246 static bool lastLayoutFitWidth;
247 static bool lastLayoutFitHeight;
248 static WritingMode lastLayoutMode;
249 static sal_Int32 lastRowCount;
250 static sal_Int32 lastColCount;
253 SdrTableObjImpl* SdrTableObjImpl::lastLayoutTable = NULL;
254 Rectangle SdrTableObjImpl::lastLayoutInputRectangle;
255 Rectangle SdrTableObjImpl::lastLayoutResultRectangle;
256 bool SdrTableObjImpl::lastLayoutFitWidth;
257 bool SdrTableObjImpl::lastLayoutFitHeight;
258 WritingMode SdrTableObjImpl::lastLayoutMode;
259 sal_Int32 SdrTableObjImpl::lastRowCount;
260 sal_Int32 SdrTableObjImpl::lastColCount;
262 SdrTableObjImpl::SdrTableObjImpl()
263 : mpTableObj( 0 )
264 , mpLayouter( 0 )
265 , mbModifyPending( false )
271 SdrTableObjImpl::~SdrTableObjImpl()
273 if( lastLayoutTable == this )
274 lastLayoutTable = NULL;
279 void SdrTableObjImpl::init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows )
281 mpTableObj = pTable;
282 mxTable = new TableModel( pTable );
283 mxTable->init( nColumns, nRows );
284 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
285 mxTable->addModifyListener( xListener );
286 mpLayouter = new TableLayouter( mxTable );
287 LayoutTable( mpTableObj->maRect, true, true );
288 mpTableObj->maLogicRect = mpTableObj->maRect;
293 SdrTableObjImpl& SdrTableObjImpl::operator=( const SdrTableObjImpl& rSource )
295 if (this != &rSource)
297 disconnectTableStyle();
299 if( mpLayouter )
301 delete mpLayouter;
302 mpLayouter = 0;
305 if( mxTable.is() )
307 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
308 mxTable->removeModifyListener( xListener );
309 mxTable->dispose();
310 mxTable.clear();
313 maTableStyle = rSource.maTableStyle;
315 mxTable = new TableModel( mpTableObj, rSource.mxTable );
316 mpLayouter = new TableLayouter( mxTable );
317 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
318 mxTable->addModifyListener( xListener );
319 mxTableStyle = rSource.mxTableStyle;
320 ApplyCellStyles();
321 mpTableObj->maRect = mpTableObj->maLogicRect;
322 LayoutTable( mpTableObj->maRect, false, false );
324 connectTableStyle();
326 return *this;
331 void SdrTableObjImpl::SetModel(SdrModel* /*pOldModel*/, SdrModel* pNewModel)
333 // try to find new table style
334 disconnectTableStyle();
336 Reference< XIndexAccess > xNewTableStyle;
337 if( mxTableStyle.is() ) try
339 const OUString sStyleName( Reference< XNamed >( mxTableStyle, UNO_QUERY_THROW )->getName() );
341 Reference< XStyleFamiliesSupplier > xSFS( pNewModel->getUnoModel(), UNO_QUERY_THROW );
342 Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), UNO_QUERY_THROW );
343 const OUString sFamilyName( "table" );
344 Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( sFamilyName ), UNO_QUERY_THROW );
346 if( xTableFamilyAccess->hasByName( sStyleName ) )
348 // found table style with the same name
349 xTableFamilyAccess->getByName( sStyleName ) >>= xNewTableStyle;
351 else
353 // copy or?
354 Reference< XIndexAccess > xIndexAccess( xTableFamilyAccess, UNO_QUERY_THROW );
355 xIndexAccess->getByIndex( 0 ) >>= xNewTableStyle;
358 catch( Exception& )
360 OSL_FAIL("svx::SdrTableObjImpl::SetModel(), exception caught!");
363 mxTableStyle = xNewTableStyle;
365 connectTableStyle();
366 update();
371 bool SdrTableObjImpl::ApplyCellStyles()
373 if( !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, true );
464 return bChanges;
469 void SdrTableObjImpl::dispose()
471 disconnectTableStyle();
472 mxTableStyle.clear();
474 if( mpLayouter )
476 delete mpLayouter;
477 mpLayouter = 0;
480 if( mxTable.is() )
482 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
483 mxTable->removeModifyListener( xListener );
484 mxTable->dispose();
485 mxTable.clear();
491 void SdrTableObjImpl::DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset )
493 if( (nEdge >= 0) && mxTable.is()) try
495 const OUString sSize( "Size" );
496 if( mbHorizontal )
498 if( (nEdge >= 0) && (nEdge <= getRowCount()) )
500 sal_Int32 nHeight = mpLayouter->getRowHeight( (!nEdge)?nEdge:(nEdge-1) );
501 if(nEdge==0)
502 nHeight -= nOffset;
503 else
504 nHeight += nOffset;
505 Reference< XIndexAccess > xRows( mxTable->getRows(), UNO_QUERY_THROW );
506 Reference< XPropertySet > xRowSet( xRows->getByIndex( (!nEdge)?nEdge:(nEdge-1) ), UNO_QUERY_THROW );
507 xRowSet->setPropertyValue( sSize, Any( nHeight ) );
510 else
513 fixes fdo#59889 and resizing of table in edge dragging
514 Total vertical edges in a NxN table is N+1, indexed from 0 to N and total Columns is N, indexed from 0 to N-1
515 In LTR table vertical edge responsible for dragging of column x(x=0 to N-1) is, Edge x+1
516 But in RTL table vertical edge responsible for dragging of column x(x=0 to N-1, but from right to left)is, Edge x
517 In LTR table dragging of edge 0(for RTL table edge N) does nothing.
519 //Todo: Implement Dragging functionality for leftmost edge of table.
520 if( (nEdge >= 0) && (nEdge <= getColumnCount()) )
522 const bool bRTL = mpTableObj != nullptr && (mpTableObj->GetWritingMode() == WritingMode_RL_TB);
523 sal_Int32 nWidth;
524 if(bRTL)
526 nWidth = mpLayouter->getColumnWidth( nEdge );
528 else
530 nWidth = mpLayouter->getColumnWidth( (!nEdge)?nEdge:(nEdge-1) );
532 Reference< XIndexAccess > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
533 nWidth += nOffset;
534 if(bRTL && nEdge<getColumnCount())
536 Reference< XPropertySet > xColSet( xCols->getByIndex( nEdge ), UNO_QUERY_THROW );
537 xColSet->setPropertyValue( sSize, Any( nWidth ) );
539 else if(!bRTL && nEdge>0)
541 Reference< XPropertySet > xColSet( xCols->getByIndex( (nEdge-1) ), UNO_QUERY_THROW );
542 xColSet->setPropertyValue( sSize, Any( nWidth ) );
544 /* To prevent the table resizing on edge dragging */
545 if( nEdge > 0 && nEdge < mxTable->getColumnCount() )
548 if( bRTL )
549 nEdge--;
551 if( (bRTL && (nEdge >= 0)) || (!bRTL && (nEdge < mxTable->getColumnCount())) )
553 nWidth = mpLayouter->getColumnWidth( nEdge );
554 nWidth = std::max( (sal_Int32)(nWidth - nOffset), (sal_Int32)0 );
556 Reference< XPropertySet > xColSet( xCols->getByIndex( nEdge ), UNO_QUERY_THROW );
557 xColSet->setPropertyValue( sSize, Any( nWidth ) );
563 catch( Exception& )
565 OSL_FAIL( "svx::SdrTableObjImpl::DragEdge(), exception caught!" );
570 // XModifyListener
573 void SAL_CALL SdrTableObjImpl::modified( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException, std::exception)
575 update();
578 void SdrTableObjImpl::update()
580 // source can be the table model itself or the assigned table template
581 TableModelNotifyGuard aGuard( mxTable.get() );
582 if( mpTableObj )
584 if( (maEditPos.mnRow >= getRowCount()) || (maEditPos.mnCol >= getColumnCount()) || (getCell( maEditPos ) != mxActiveCell) )
586 if(maEditPos.mnRow >= getRowCount())
587 maEditPos.mnRow = getRowCount()-1;
589 if(maEditPos.mnCol >= getColumnCount())
590 maEditPos.mnCol = getColumnCount()-1;
592 mpTableObj->setActiveCell( maEditPos );
595 ApplyCellStyles();
597 mpTableObj->maRect = mpTableObj->maLogicRect;
598 LayoutTable( mpTableObj->maRect, false, false );
600 mpTableObj->SetRectsDirty();
601 mpTableObj->ActionChanged();
602 mpTableObj->BroadcastObjectChange();
608 void SdrTableObjImpl::connectTableStyle()
610 if( mxTableStyle.is() )
612 Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY );
613 if( xBroadcaster.is() )
615 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
616 xBroadcaster->addModifyListener( xListener );
623 void SdrTableObjImpl::disconnectTableStyle()
625 if( mxTableStyle.is() )
627 Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY );
628 if( xBroadcaster.is() )
630 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
631 xBroadcaster->removeModifyListener( xListener );
638 bool SdrTableObjImpl::isInUse()
640 return mpTableObj && mpTableObj->IsInserted();
644 // XEventListener
647 void SAL_CALL SdrTableObjImpl::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException, std::exception)
649 mxActiveCell.clear();
650 mxTable.clear();
651 if( mpLayouter )
653 delete mpLayouter;
654 mpLayouter = 0;
656 mpTableObj = 0;
661 CellRef SdrTableObjImpl::getCell( const CellPos& rPos ) const
663 CellRef xCell;
664 if( mxTable.is() ) try
666 xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
668 catch( Exception& )
670 OSL_FAIL( "svx::SdrTableObjImpl::getCell(), exception caught!" );
672 return xCell;
677 sal_Int32 SdrTableObjImpl::getColumnCount() const
679 return mxTable.is() ? mxTable->getColumnCount() : 0;
684 sal_Int32 SdrTableObjImpl::getRowCount() const
686 return mxTable.is() ? mxTable->getRowCount() : 0;
689 void SdrTableObjImpl::LayoutTable( Rectangle& rArea, bool bFitWidth, bool bFitHeight )
691 if( mpLayouter && mpTableObj->GetModel() )
693 // Optimization: SdrTableObj::SetChanged() can call this very often, repeatedly
694 // with the same settings, noticeably increasing load time. Skip if already done.
695 bool bInteractiveMightGrowBecauseTextChanged =
696 mpTableObj->IsReallyEdited() && (mpTableObj->IsAutoGrowHeight() || mpTableObj->IsAutoGrowWidth());
697 WritingMode writingMode = mpTableObj->GetWritingMode();
698 if( bInteractiveMightGrowBecauseTextChanged
699 || lastLayoutTable != this || lastLayoutInputRectangle != rArea
700 || lastLayoutFitWidth != bFitWidth || lastLayoutFitHeight != bFitHeight
701 || lastLayoutMode != writingMode
702 || lastRowCount != getRowCount()
703 || lastColCount != getColumnCount() )
705 lastLayoutTable = this;
706 lastLayoutInputRectangle = rArea;
707 lastLayoutFitWidth = bFitWidth;
708 lastLayoutFitHeight = bFitHeight;
709 lastLayoutMode = writingMode;
710 lastRowCount = getRowCount();
711 lastColCount = getColumnCount();
712 TableModelNotifyGuard aGuard( mxTable.get() );
713 mpLayouter->LayoutTable( rArea, bFitWidth, bFitHeight );
714 lastLayoutResultRectangle = rArea;
716 else
718 rArea = lastLayoutResultRectangle;
723 void SdrTableObjImpl::UpdateCells( Rectangle& rArea )
725 if( mpLayouter && mxTable.is() )
727 TableModelNotifyGuard aGuard( mxTable.get() );
728 mpLayouter->updateCells( rArea );
729 mxTable->setModified(true);
734 // BaseProperties section
737 sdr::properties::BaseProperties* SdrTableObj::CreateObjectSpecificProperties()
739 return new TableProperties(*this);
743 // DrawContact section
746 sdr::contact::ViewContact* SdrTableObj::CreateObjectSpecificViewContact()
748 return new sdr::contact::ViewContactOfTableObj(*this);
753 TYPEINIT1(SdrTableObj,SdrTextObj);
757 SdrTableObj::SdrTableObj(SdrModel* _pModel)
759 pModel = _pModel;
760 init( 1, 1 );
765 SdrTableObj::SdrTableObj(SdrModel* _pModel, const ::Rectangle& rNewRect, sal_Int32 nColumns, sal_Int32 nRows)
766 : SdrTextObj( rNewRect )
767 , maLogicRect( rNewRect )
769 pModel = _pModel;
771 if( nColumns <= 0 )
772 nColumns = 1;
774 if( nRows <= 0 )
775 nRows = 1;
777 init( nColumns, nRows );
782 void SdrTableObj::init( sal_Int32 nColumns, sal_Int32 nRows )
784 bClosedObj = true;
786 mpImpl = new SdrTableObjImpl;
787 mpImpl->acquire();
788 mpImpl->init( this, nColumns, nRows );
793 SdrTableObj::~SdrTableObj()
795 mpImpl->dispose();
796 mpImpl->release();
800 // table stuff
803 Reference< XTable > SdrTableObj::getTable() const
805 return Reference< XTable >( mpImpl->mxTable.get() );
810 bool SdrTableObj::isValid( const CellPos& rPos ) const
812 return (rPos.mnCol >= 0) && (rPos.mnCol < mpImpl->getColumnCount()) && (rPos.mnRow >= 0) && (rPos.mnRow < mpImpl->getRowCount());
817 CellPos SdrTableObj::getFirstCell()
819 return CellPos( 0,0 );
824 CellPos SdrTableObj::getLastCell() const
826 CellPos aPos;
827 if( mpImpl->mxTable.is() )
829 aPos.mnCol = mpImpl->getColumnCount()-1;
830 aPos.mnRow = mpImpl->getRowCount()-1;
832 return aPos;
837 CellPos SdrTableObj::getLeftCell( const CellPos& rPos, bool bEdgeTravel ) const
839 switch( GetWritingMode() )
841 default:
842 case WritingMode_LR_TB:
843 return getPreviousCell( rPos, bEdgeTravel );
844 case WritingMode_RL_TB:
845 return getNextCell( rPos, bEdgeTravel );
846 case WritingMode_TB_RL:
847 return getPreviousRow( rPos, bEdgeTravel );
853 CellPos SdrTableObj::getRightCell( const CellPos& rPos, bool bEdgeTravel ) const
855 switch( GetWritingMode() )
857 default:
858 case WritingMode_LR_TB:
859 return getNextCell( rPos, bEdgeTravel );
860 case WritingMode_RL_TB:
861 return getPreviousCell( rPos, bEdgeTravel );
862 case WritingMode_TB_RL:
863 return getNextRow( rPos, bEdgeTravel );
869 CellPos SdrTableObj::getUpCell( const CellPos& rPos, bool bEdgeTravel ) const
871 switch( GetWritingMode() )
873 default:
874 case WritingMode_LR_TB:
875 case WritingMode_RL_TB:
876 return getPreviousRow( rPos, bEdgeTravel );
877 case WritingMode_TB_RL:
878 return getPreviousCell( rPos, bEdgeTravel );
884 CellPos SdrTableObj::getDownCell( const CellPos& rPos, bool bEdgeTravel ) const
886 switch( GetWritingMode() )
888 default:
889 case WritingMode_LR_TB:
890 case WritingMode_RL_TB:
891 return getNextRow( rPos, bEdgeTravel );
892 case WritingMode_TB_RL:
893 return getNextCell( rPos, bEdgeTravel );
899 CellPos SdrTableObj::getPreviousCell( const CellPos& rPos, bool bEdgeTravel ) const
901 CellPos aPos( rPos );
902 if( mpImpl )
904 CellRef xCell( mpImpl->getCell( aPos ) );
905 if( xCell.is() && xCell->isMerged() )
907 sal_Int32 nTemp = 0;
908 findMergeOrigin( mpImpl->mxTable.get(), aPos.mnCol, aPos.mnRow, aPos.mnCol, nTemp );
911 if( aPos.mnCol > 0 )
913 --aPos.mnCol;
916 else if( bEdgeTravel && (aPos.mnRow > 0) )
918 aPos.mnCol = mpImpl->mxTable->getColumnCount()-1;
919 --aPos.mnRow;
922 return aPos;
927 CellPos SdrTableObj::getNextCell( const CellPos& rPos, bool bEdgeTravel ) const
929 CellPos aPos( rPos );
930 if( mpImpl )
932 CellRef xCell( mpImpl->getCell( aPos ) );
933 if( xCell.is() )
935 if( xCell->isMerged() )
937 findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow );
939 xCell = mpImpl->getCell(aPos);
941 if( xCell.is() )
943 aPos.mnCol += xCell->getColumnSpan();
944 aPos.mnRow = rPos.mnRow;
947 else
949 aPos.mnCol += xCell->getColumnSpan();
952 if( aPos.mnCol < mpImpl->mxTable->getColumnCount() )
953 return aPos;
955 if( bEdgeTravel && ((aPos.mnRow + 1) < mpImpl->getRowCount()) )
957 aPos.mnCol = 0;
958 aPos.mnRow += 1;
959 return aPos;
964 // last cell reached, no traveling possible
965 return rPos;
970 CellPos SdrTableObj::getPreviousRow( const CellPos& rPos, bool bEdgeTravel ) const
972 CellPos aPos( rPos );
973 if( mpImpl )
975 CellRef xCell( mpImpl->getCell( aPos ) );
976 if( xCell.is() )
978 if( xCell->isMerged() )
980 sal_Int32 nTemp = 0;
981 findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, nTemp, aPos.mnRow );
985 if( aPos.mnRow > 0 )
987 --aPos.mnRow;
989 else if( bEdgeTravel && (aPos.mnCol > 0) )
991 aPos.mnRow = mpImpl->mxTable->getRowCount()-1;
992 --aPos.mnCol;
995 return aPos;
1000 CellPos SdrTableObj::getNextRow( const CellPos& rPos, bool bEdgeTravel ) const
1002 CellPos aPos( rPos );
1004 if( mpImpl )
1006 CellRef xCell( mpImpl->getCell( rPos ) );
1007 if( xCell.is() )
1009 if( xCell->isMerged() )
1011 findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow );
1012 xCell = mpImpl->getCell(aPos);
1013 aPos.mnCol = rPos.mnCol;
1016 if( xCell.is() )
1017 aPos.mnRow += xCell->getRowSpan();
1019 if( aPos.mnRow < mpImpl->mxTable->getRowCount() )
1020 return aPos;
1022 if( bEdgeTravel && (aPos.mnCol + 1) < mpImpl->mxTable->getColumnCount() )
1024 aPos.mnRow = 0;
1025 aPos.mnCol += 1;
1027 while( aPos.mnCol < mpImpl->mxTable->getColumnCount() )
1029 xCell = mpImpl->getCell( aPos );
1030 if( xCell.is() && !xCell->isMerged() )
1031 return aPos;
1032 aPos.mnCol += 1;
1038 // last position reached, no more traveling possible
1039 return rPos;
1044 const TableStyleSettings& SdrTableObj::getTableStyleSettings() const
1046 if( mpImpl )
1048 return mpImpl->maTableStyle;
1050 else
1052 static TableStyleSettings aTmp;
1053 return aTmp;
1059 void SdrTableObj::setTableStyleSettings( const TableStyleSettings& rStyle )
1061 if( mpImpl )
1063 mpImpl->maTableStyle = rStyle;
1064 mpImpl->update();
1070 TableHitKind SdrTableObj::CheckTableHit( const Point& rPos, sal_Int32& rnX, sal_Int32& rnY, int nTol ) const
1072 if( !mpImpl || !mpImpl->mxTable.is() )
1073 return SDRTABLEHIT_NONE;
1075 rnX = 0;
1076 rnY = 0;
1078 const sal_Int32 nColCount = mpImpl->getColumnCount();
1079 const sal_Int32 nRowCount = mpImpl->getRowCount();
1081 sal_Int32 nX = rPos.X() + nTol - maRect.Left();
1082 sal_Int32 nY = rPos.Y() + nTol - maRect.Top();
1084 if( (nX < 0) || (nX > (maRect.GetWidth() + nTol)) || (nY < 0) || (nY > (maRect.GetHeight() + nTol) ) )
1085 return SDRTABLEHIT_NONE;
1087 // get vertical edge number and check for a hit
1088 const bool bRTL = (GetWritingMode() == WritingMode_RL_TB);
1089 bool bVrtHit = false;
1090 if( nX >= 0 )
1092 if( !bRTL )
1094 while( rnX <= nColCount )
1096 if( nX <= (2*nTol) )
1098 bVrtHit = true;
1099 break;
1102 if( rnX == nColCount )
1103 break;
1105 nX -= mpImpl->mpLayouter->getColumnWidth( rnX );
1106 if( nX < 0 )
1107 break;
1108 rnX++;
1111 else
1113 rnX = nColCount;
1114 while( rnX >= 0 )
1116 if( nX <= (2*nTol) )
1118 bVrtHit = true;
1119 break;
1122 if( rnX == 0 )
1123 break;
1125 rnX--;
1126 nX -= mpImpl->mpLayouter->getColumnWidth( rnX );
1127 if( nX < 0 )
1128 break;
1133 // rnX is now the edge number left to the pointer, if it was hit bHrzHit is also true
1135 // get vertical edge number and check for a hit
1136 bool bHrzHit = false;
1137 if( nY >= 0 )
1139 while( rnY <= nRowCount )
1141 if( nY <= (2*nTol) )
1143 bHrzHit = true;
1144 break;
1147 if( rnY == nRowCount )
1148 break;
1150 nY -= mpImpl->mpLayouter->getRowHeight(rnY);
1151 if( nY < 0 )
1152 break;
1153 rnY++;
1157 // rnY is now the edge number above the pointer, if it was hit bVrtHit is also true
1159 if( bVrtHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, false ) )
1160 return SDRTABLEHIT_VERTICAL_BORDER;
1162 if( bHrzHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, true ) )
1163 return SDRTABLEHIT_HORIZONTAL_BORDER;
1165 CellRef xCell( mpImpl->getCell( CellPos( rnX, rnY ) ) );
1166 if( xCell.is() && xCell->isMerged() )
1167 findMergeOrigin( mpImpl->mxTable.get(), rnX, rnY, rnX, rnY );
1169 if( xCell.is() )
1171 nX += mpImpl->mpLayouter->getColumnWidth( rnX );
1172 //Fix for fdo#62673 : non-editable cell in table on cell merge
1173 sal_Int32 i=0;
1174 while(xCell.is() && xCell->isMerged())
1176 nX += mpImpl->mpLayouter->getColumnWidth( rnX+i );
1177 i++;
1178 if(rnX+i < nColCount)
1179 xCell=mpImpl->getCell( CellPos( rnX+i, rnY) );
1180 else
1181 break;
1184 if( nX < xCell->GetTextLeftDistance() )
1185 return SDRTABLEHIT_CELL;
1188 return SDRTABLEHIT_CELLTEXTAREA;
1191 const SfxItemSet& SdrTableObj::GetActiveCellItemSet() const
1193 return getActiveCell()->GetItemSet();
1198 void SdrTableObj::setTableStyle( const Reference< XIndexAccess >& xTableStyle )
1200 if( mpImpl && (mpImpl->mxTableStyle != xTableStyle) )
1202 mpImpl->disconnectTableStyle();
1203 mpImpl->mxTableStyle = xTableStyle;
1204 mpImpl->connectTableStyle();
1205 mpImpl->update();
1211 const Reference< XIndexAccess >& SdrTableObj::getTableStyle() const
1213 if( mpImpl )
1215 return mpImpl->mxTableStyle;
1217 else
1219 static Reference< XIndexAccess > aTmp;
1220 return aTmp;
1225 // text stuff
1228 /** returns the currently active text. */
1229 SdrText* SdrTableObj::getActiveText() const
1231 return dynamic_cast< SdrText* >( getActiveCell().get() );
1236 /** returns the nth available text. */
1237 SdrText* SdrTableObj::getText( sal_Int32 nIndex ) const
1239 if( mpImpl->mxTable.is() )
1241 const sal_Int32 nColCount = mpImpl->getColumnCount();
1242 if( nColCount )
1244 CellPos aPos( nIndex % nColCount, nIndex / nColCount );
1246 CellRef xCell( mpImpl->getCell( aPos ) );
1247 return dynamic_cast< SdrText* >( xCell.get() );
1250 return 0;
1255 /** returns the number of texts available for this object. */
1256 sal_Int32 SdrTableObj::getTextCount() const
1258 if( mpImpl->mxTable.is() )
1260 const sal_Int32 nColCount = mpImpl->getColumnCount();
1261 const sal_Int32 nRowCount = mpImpl->getRowCount();
1263 return nColCount * nRowCount;
1265 else
1267 return 0;
1273 /** changes the current active text */
1274 void SdrTableObj::setActiveText( sal_Int32 nIndex )
1276 if( mpImpl && mpImpl->mxTable.is() )
1278 const sal_Int32 nColCount = mpImpl->mxTable->getColumnCount();
1279 if( nColCount )
1281 CellPos aPos( nIndex % nColCount, nIndex / nColCount );
1282 if( isValid( aPos ) )
1283 setActiveCell( aPos );
1290 /** returns the index of the text that contains the given point or -1 */
1291 sal_Int32 SdrTableObj::CheckTextHit(const Point& rPnt) const
1293 if( mpImpl && mpImpl->mxTable.is() )
1295 CellPos aPos;
1296 if( CheckTableHit( rPnt, aPos.mnCol, aPos.mnRow, 0 ) == SDRTABLEHIT_CELLTEXTAREA )
1297 return aPos.mnRow * mpImpl->mxTable->getColumnCount() + aPos.mnCol;
1300 return 0;
1303 SdrOutliner* SdrTableObj::GetCellTextEditOutliner( const Cell& rCell ) const
1305 if( mpImpl && (mpImpl->getCell( mpImpl->maEditPos ).get() == &rCell) )
1306 return pEdtOutl;
1307 else
1308 return 0;
1311 const TableLayouter& SdrTableObj::getTableLayouter() const
1313 assert(mpImpl && mpImpl->mpLayouter && "getTableLayouter() error: no mpImpl or mpLayouter (!)");
1314 return *(mpImpl->mpLayouter);
1317 bool SdrTableObj::IsAutoGrowHeight() const
1319 return true;
1322 bool SdrTableObj::IsAutoGrowWidth() const
1324 return true;
1327 bool SdrTableObj::HasText() const
1329 return true;
1332 bool SdrTableObj::IsTextEditActive( const CellPos& rPos )
1334 return pEdtOutl && mpImpl && (rPos == mpImpl->maEditPos);
1339 void SdrTableObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
1341 if( (pEditStatus->GetStatusWord() & EditStatusFlags::TEXTHEIGHTCHANGED) && mpImpl && mpImpl->mpLayouter )
1343 Rectangle aRect0( maRect );
1344 maRect = maLogicRect;
1345 mpImpl->LayoutTable( maRect, false, false );
1346 SetRectsDirty();
1347 ActionChanged();
1348 BroadcastObjectChange();
1349 if (aRect0 != maRect)
1350 SendUserCall(SDRUSERCALL_RESIZE,aRect0);
1356 void SdrTableObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
1358 rInfo.bResizeFreeAllowed=true;
1359 rInfo.bResizePropAllowed=true;
1360 rInfo.bRotateFreeAllowed=false;
1361 rInfo.bRotate90Allowed =false;
1362 rInfo.bMirrorFreeAllowed=false;
1363 rInfo.bMirror45Allowed =false;
1364 rInfo.bMirror90Allowed =false;
1366 // allow transparence
1367 rInfo.bTransparenceAllowed = true;
1369 // gradient depends on fillstyle
1370 drawing::FillStyle eFillStyle = static_cast<const XFillStyleItem&>(GetObjectItem(XATTR_FILLSTYLE)).GetValue();
1371 rInfo.bGradientAllowed = (eFillStyle == drawing::FillStyle_GRADIENT);
1372 rInfo.bShearAllowed =false;
1373 rInfo.bEdgeRadiusAllowed=false;
1374 rInfo.bCanConvToPath =false;
1375 rInfo.bCanConvToPoly =false;
1376 rInfo.bCanConvToPathLineToArea=false;
1377 rInfo.bCanConvToPolyLineToArea=false;
1378 rInfo.bCanConvToContour = false;
1383 sal_uInt16 SdrTableObj::GetObjIdentifier() const
1385 return static_cast<sal_uInt16>(OBJ_TABLE);
1390 void SdrTableObj::SetPage(SdrPage* pNewPage)
1392 SdrTextObj::SetPage(pNewPage);
1397 void SdrTableObj::SetModel(SdrModel* pNewModel)
1399 SdrModel* pOldModel = GetModel();
1400 if( pNewModel != pOldModel )
1402 SdrTextObj::SetModel(pNewModel);
1404 if( mpImpl )
1406 mpImpl->SetModel( pOldModel, pNewModel );
1408 if( !maLogicRect.IsEmpty() )
1410 maRect = maLogicRect;
1411 mpImpl->LayoutTable( maRect, false, false );
1419 void SdrTableObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, bool bNoEditText, Rectangle* pAnchorRect, bool bLineWidth ) const
1421 if( mpImpl )
1422 TakeTextRect( mpImpl->maEditPos, rOutliner, rTextRect, bNoEditText, pAnchorRect, bLineWidth );
1427 void SdrTableObj::TakeTextRect( const CellPos& rPos, SdrOutliner& rOutliner, Rectangle& rTextRect, bool bNoEditText, Rectangle* pAnchorRect, bool /*bLineWidth*/ ) const
1429 if( !mpImpl )
1430 return;
1432 CellRef xCell( mpImpl->getCell( rPos ) );
1433 if( !xCell.is() )
1434 return;
1436 Rectangle aAnkRect;
1437 TakeTextAnchorRect( rPos, aAnkRect );
1439 SdrTextVertAdjust eVAdj=xCell->GetTextVerticalAdjust();
1441 EEControlBits nStat0=rOutliner.GetControlWord();
1442 Size aNullSize;
1443 nStat0 |= EEControlBits::AUTOPAGESIZE;
1444 rOutliner.SetControlWord(nStat0);
1445 rOutliner.SetMinAutoPaperSize(aNullSize);
1446 rOutliner.SetMaxAutoPaperSize(aAnkRect.GetSize());
1447 rOutliner.SetPaperSize(aAnkRect.GetSize());
1449 // #103516# New try with _BLOCK for hor and ver after completely
1450 // supporting full width for vertical text.
1451 // if( SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
1452 // {
1453 rOutliner.SetMinAutoPaperSize(Size(aAnkRect.GetWidth(), 0));
1454 // }
1455 // else if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
1456 // {
1457 // rOutliner.SetMinAutoPaperSize(Size(0, aAnkRect.GetHeight()));
1458 // }
1462 // set text at outliner, maybe from edit outliner
1463 OutlinerParaObject* pPara= xCell->GetOutlinerParaObject();
1464 if (pEdtOutl && !bNoEditText && mpImpl->mxActiveCell == xCell )
1465 pPara=pEdtOutl->CreateParaObject();
1467 if (pPara)
1469 const bool bHitTest = pModel && (&pModel->GetHitTestOutliner() == &rOutliner);
1471 const SdrTextObj* pTestObj = rOutliner.GetTextObj();
1472 if( !pTestObj || !bHitTest || (pTestObj != this) || (pTestObj->GetOutlinerParaObject() != xCell->GetOutlinerParaObject()) )
1474 if( bHitTest ) // #i33696# take back fix #i27510#
1475 rOutliner.SetTextObj( this );
1477 rOutliner.SetUpdateMode(true);
1478 rOutliner.SetText(*pPara);
1481 else
1483 rOutliner.SetTextObj( NULL );
1486 if (pEdtOutl && !bNoEditText && pPara && mpImpl->mxActiveCell == xCell )
1487 delete pPara;
1489 rOutliner.SetUpdateMode(true);
1490 rOutliner.SetControlWord(nStat0);
1492 Point aTextPos(aAnkRect.TopLeft());
1493 Size aTextSiz(rOutliner.GetPaperSize());
1494 if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1496 long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
1497 if (eVAdj==SDRTEXTVERTADJUST_CENTER)
1498 aTextPos.Y()+=nFreeHgt/2;
1499 if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1500 aTextPos.Y()+=nFreeHgt;
1503 if (pAnchorRect)
1504 *pAnchorRect=aAnkRect;
1506 rTextRect=Rectangle(aTextPos,aTextSiz);
1511 const CellRef& SdrTableObj::getActiveCell() const
1513 if( mpImpl )
1515 if( !mpImpl->mxActiveCell.is() )
1517 CellPos aPos;
1518 const_cast< SdrTableObj* >(this)->setActiveCell( aPos );
1520 return mpImpl->mxActiveCell;
1522 else
1524 static CellRef xCell;
1525 return xCell;
1531 sal_Int32 SdrTableObj::getColumnCount() const
1533 return mpImpl ? mpImpl->getColumnCount() : 0;
1538 void SdrTableObj::setActiveCell( const CellPos& rPos )
1540 if( mpImpl && mpImpl->mxTable.is() ) try
1542 mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
1543 if( mpImpl->mxActiveCell.is() && mpImpl->mxActiveCell->isMerged() )
1545 CellPos aOrigin;
1546 findMergeOrigin( mpImpl->mxTable.get(), rPos.mnCol, rPos.mnRow, aOrigin.mnCol, aOrigin.mnRow );
1547 mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( aOrigin.mnCol, aOrigin.mnRow ).get() ) );
1548 mpImpl->maEditPos = aOrigin;
1550 else
1552 mpImpl->maEditPos = rPos;
1555 catch( Exception& )
1557 OSL_FAIL("SdrTableObj::setActiveCell(), exception caught!");
1563 void SdrTableObj::getActiveCellPos( CellPos& rPos ) const
1565 rPos = mpImpl->maEditPos;
1570 void SdrTableObj::getCellBounds( const CellPos& rPos, ::Rectangle& rCellRect )
1572 if( mpImpl )
1574 CellRef xCell( mpImpl->getCell( rPos ) );
1575 if( xCell.is() )
1576 rCellRect = xCell->getCellRect();
1582 void SdrTableObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
1584 if( mpImpl )
1585 TakeTextAnchorRect( mpImpl->maEditPos, rAnchorRect );
1590 void SdrTableObj::TakeTextAnchorRect( const CellPos& rPos, Rectangle& rAnchorRect ) const
1592 Rectangle aAnkRect(maRect);
1594 if( mpImpl )
1596 CellRef xCell( mpImpl->getCell( rPos ) );
1597 if( xCell.is() )
1598 xCell->TakeTextAnchorRect( aAnkRect );
1601 ImpJustifyRect(aAnkRect);
1602 rAnchorRect=aAnkRect;
1607 void SdrTableObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
1609 if( mpImpl )
1610 TakeTextEditArea( mpImpl->maEditPos, pPaperMin, pPaperMax, pViewInit, pViewMin );
1615 void SdrTableObj::TakeTextEditArea( const CellPos& rPos, Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin ) const
1617 Size aPaperMin,aPaperMax;
1618 Rectangle aViewInit;
1619 TakeTextAnchorRect( rPos, aViewInit );
1621 Size aAnkSiz(aViewInit.GetSize());
1622 aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert
1624 Size aMaxSiz(aAnkSiz.Width(),1000000);
1625 if (pModel!=NULL)
1627 Size aTmpSiz(pModel->GetMaxObjSize());
1628 if (aTmpSiz.Height()!=0)
1629 aMaxSiz.Height()=aTmpSiz.Height();
1632 CellRef xCell( mpImpl->getCell( rPos ) );
1633 SdrTextVertAdjust eVAdj = xCell.is() ? xCell->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_TOP;
1635 aPaperMax=aMaxSiz;
1637 aPaperMin.Width() = aAnkSiz.Width();
1639 if (pViewMin!=NULL)
1641 *pViewMin=aViewInit;
1642 long nYFree=aAnkSiz.Height()-aPaperMin.Height();
1644 if (eVAdj==SDRTEXTVERTADJUST_TOP)
1646 pViewMin->Bottom()-=nYFree;
1648 else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1650 pViewMin->Top()+=nYFree;
1652 else
1654 pViewMin->Top()+=nYFree/2;
1655 pViewMin->Bottom()=pViewMin->Top()+aPaperMin.Height();
1660 if(IsVerticalWriting())
1661 aPaperMin.Width() = 0;
1662 else
1663 aPaperMin.Height() = 0;
1665 if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
1666 if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
1667 if (pViewInit!=NULL) *pViewInit=aViewInit;
1672 sal_uInt16 SdrTableObj::GetOutlinerViewAnchorMode() const
1674 EVAnchorMode eRet=ANCHOR_TOP_LEFT;
1675 CellRef xCell( getActiveCell() );
1676 if( xCell.is() )
1678 SdrTextVertAdjust eV=xCell->GetTextVerticalAdjust();
1681 if (eV==SDRTEXTVERTADJUST_TOP)
1683 eRet=ANCHOR_TOP_LEFT;
1685 else if (eV==SDRTEXTVERTADJUST_BOTTOM)
1687 eRet=ANCHOR_BOTTOM_LEFT;
1689 else
1691 eRet=ANCHOR_VCENTER_LEFT;
1695 return (sal_uInt16)eRet;
1700 OutlinerParaObject* SdrTableObj::GetEditOutlinerParaObject() const
1702 return SdrTextObj::GetEditOutlinerParaObject();
1705 OUString SdrTableObj::TakeObjNameSingul() const
1707 OUStringBuffer sName(ImpGetResStr(STR_ObjNameSingulTable));
1709 OUString aName(GetName());
1710 if (!aName.isEmpty())
1712 sName.append(' ');
1713 sName.append('\'');
1714 sName.append(aName);
1715 sName.append('\'');
1718 return sName.makeStringAndClear();
1723 OUString SdrTableObj::TakeObjNamePlural() const
1725 return ImpGetResStr(STR_ObjNamePluralTable);
1730 SdrTableObj* SdrTableObj::Clone() const
1732 return CloneHelper< SdrTableObj >();
1735 SdrTableObj& SdrTableObj::operator=(const SdrTableObj& rObj)
1737 if( this == &rObj )
1738 return *this;
1739 // call parent
1740 SdrObject::operator=(rObj);
1742 TableModelNotifyGuard aGuard( mpImpl ? mpImpl->mxTable.get() : 0 );
1744 maLogicRect = rObj.maLogicRect;
1745 maRect = rObj.maRect;
1746 aGeo = rObj.aGeo;
1747 eTextKind = rObj.eTextKind;
1748 bTextFrame = rObj.bTextFrame;
1749 aTextSize = rObj.aTextSize;
1750 bTextSizeDirty = rObj.bTextSizeDirty;
1751 bNoShear = rObj.bNoShear;
1752 bNoRotate = rObj.bNoRotate;
1753 bNoMirror = rObj.bNoMirror;
1754 bDisableAutoWidthOnDragging = rObj.bDisableAutoWidthOnDragging;
1756 if (mpImpl && rObj.mpImpl)
1757 *mpImpl = *rObj.mpImpl;
1758 return *this;
1763 basegfx::B2DPolyPolygon SdrTableObj::TakeXorPoly() const
1765 return SdrTextObj::TakeXorPoly();
1770 basegfx::B2DPolyPolygon SdrTableObj::TakeContour() const
1772 return SdrTextObj::TakeContour();
1777 const Rectangle& SdrTableObj::GetSnapRect() const
1779 return maRect;
1784 void SdrTableObj::NbcSetSnapRect(const Rectangle& rRect)
1786 NbcSetLogicRect( rRect );
1791 const Rectangle& SdrTableObj::GetLogicRect() const
1793 return maLogicRect;
1798 void SdrTableObj::RecalcSnapRect()
1804 sal_uInt32 SdrTableObj::GetSnapPointCount() const
1806 return SdrTextObj::GetSnapPointCount();
1812 Point SdrTableObj::GetSnapPoint(sal_uInt32 i) const
1814 return SdrTextObj::GetSnapPoint(i);
1819 bool SdrTableObj::BegTextEdit(SdrOutliner& rOutl)
1821 if( pEdtOutl != NULL )
1822 return false;
1824 pEdtOutl=&rOutl;
1826 mbInEditMode = true;
1828 rOutl.Init( OUTLINERMODE_TEXTOBJECT );
1829 rOutl.SetRefDevice( pModel->GetRefDevice() );
1831 bool bUpdMerk=rOutl.GetUpdateMode();
1832 if (bUpdMerk) rOutl.SetUpdateMode(false);
1833 Size aPaperMin;
1834 Size aPaperMax;
1835 Rectangle aEditArea;
1836 TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL);
1838 rOutl.SetMinAutoPaperSize(aPaperMin);
1839 rOutl.SetMaxAutoPaperSize(aPaperMax);
1840 rOutl.SetPaperSize(aPaperMax);
1842 if (bUpdMerk) rOutl.SetUpdateMode(true);
1844 EEControlBits nStat=rOutl.GetControlWord();
1845 nStat |= EEControlBits::AUTOPAGESIZE;
1846 nStat &=~EEControlBits::STRETCHING;
1847 rOutl.SetControlWord(nStat);
1849 OutlinerParaObject* pPara = GetOutlinerParaObject();
1850 if(pPara)
1851 rOutl.SetText(*pPara);
1853 rOutl.UpdateFields();
1854 rOutl.ClearModifyFlag();
1856 return true;
1861 void SdrTableObj::EndTextEdit(SdrOutliner& rOutl)
1863 if(rOutl.IsModified())
1865 if( GetModel() && GetModel()->IsUndoEnabled() )
1866 GetModel()->AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*this) );
1868 OutlinerParaObject* pNewText = 0;
1869 Paragraph* p1stPara = rOutl.GetParagraph( 0 );
1870 sal_Int32 nParaAnz = rOutl.GetParagraphCount();
1872 if(p1stPara)
1874 if(nParaAnz == 1)
1876 // if its only one paragraph, check if it is empty
1877 OUString aStr(rOutl.GetText(p1stPara));
1878 if (aStr.isEmpty())
1880 // gotcha!
1881 nParaAnz = 0;
1885 // to remove the grey field background
1886 rOutl.UpdateFields();
1888 if(nParaAnz != 0)
1890 // create new text object
1891 pNewText = rOutl.CreateParaObject( 0, nParaAnz );
1894 SetOutlinerParaObject(pNewText);
1897 pEdtOutl = 0;
1898 rOutl.Clear();
1899 EEControlBits nStat = rOutl.GetControlWord();
1900 nStat &= ~EEControlBits::AUTOPAGESIZE;
1901 rOutl.SetControlWord(nStat);
1903 mbInEditMode = false;
1908 OutlinerParaObject* SdrTableObj::GetOutlinerParaObject() const
1910 CellRef xCell( getActiveCell() );
1911 if( xCell.is() )
1912 return xCell->GetOutlinerParaObject();
1913 else
1914 return 0;
1919 void SdrTableObj::NbcSetOutlinerParaObject( OutlinerParaObject* pTextObject)
1921 CellRef xCell( getActiveCell() );
1922 if( xCell.is() )
1924 if( pModel )
1926 // Update HitTestOutliner
1927 const SdrTextObj* pTestObj = pModel->GetHitTestOutliner().GetTextObj();
1928 if( pTestObj && pTestObj->GetOutlinerParaObject() == xCell->GetOutlinerParaObject() )
1929 pModel->GetHitTestOutliner().SetTextObj( NULL );
1932 xCell->SetOutlinerParaObject( pTextObject );
1934 SetTextSizeDirty();
1935 NbcAdjustTextFrameWidthAndHeight();
1941 void SdrTableObj::NbcSetLogicRect(const Rectangle& rRect)
1943 maLogicRect=rRect;
1944 ImpJustifyRect(maLogicRect);
1945 const bool bWidth = maLogicRect.getWidth() != maRect.getWidth();
1946 const bool bHeight = maLogicRect.getHeight() != maRect.getHeight();
1947 maRect = maLogicRect;
1948 NbcAdjustTextFrameWidthAndHeight( !bHeight, !bWidth );
1949 SetRectsDirty();
1955 void SdrTableObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool /* bShrinkOnly = false */ )
1957 Rectangle aAdjustRect( rMaxRect );
1958 aAdjustRect.setHeight( GetLogicRect().getHeight() );
1959 SetLogicRect( aAdjustRect );
1964 void SdrTableObj::NbcMove(const Size& rSiz)
1966 MoveRect(maLogicRect,rSiz);
1967 SdrTextObj::NbcMove( rSiz );
1968 if( mpImpl )
1969 mpImpl->UpdateCells( maRect );
1974 void SdrTableObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1976 Rectangle aOldRect( maLogicRect );
1977 ResizeRect(maLogicRect,rRef,xFact,yFact);
1979 maRect = maLogicRect;
1980 NbcAdjustTextFrameWidthAndHeight( maLogicRect.GetHeight() == aOldRect.GetHeight(), maLogicRect.GetWidth() == aOldRect.GetWidth() );
1981 SetRectsDirty();
1986 bool SdrTableObj::AdjustTextFrameWidthAndHeight(bool bHgt, bool bWdt)
1988 Rectangle aNeuRect(maLogicRect);
1989 bool bRet=AdjustTextFrameWidthAndHeight(aNeuRect,bHgt,bWdt);
1990 if (bRet)
1992 Rectangle aBoundRect0;
1993 if (pUserCall!=NULL)
1994 aBoundRect0=GetLastBoundRect();
1995 maRect = aNeuRect;
1996 SetRectsDirty();
1997 SetChanged();
1998 BroadcastObjectChange();
1999 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2001 return bRet;
2006 bool SdrTableObj::AdjustTextFrameWidthAndHeight(Rectangle& rR, bool bHeight, bool bWidth) const
2008 if((pModel == NULL) || rR.IsEmpty() || !mpImpl || !mpImpl->mxTable.is() )
2009 return false;
2011 Rectangle aRectangle( rR );
2012 mpImpl->LayoutTable( aRectangle, !bWidth, !bHeight );
2014 if( aRectangle != rR )
2016 rR = aRectangle;
2017 return true;
2019 else
2021 return false;
2027 void SdrTableObj::NbcReformatText()
2029 NbcAdjustTextFrameWidthAndHeight();
2034 void SdrTableObj::ReformatText()
2036 Rectangle aBoundRect0;
2037 if (pUserCall!=NULL)
2038 aBoundRect0=GetLastBoundRect();
2039 NbcReformatText();
2040 SetChanged();
2041 BroadcastObjectChange();
2042 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2047 bool SdrTableObj::IsVerticalWriting() const
2049 const SvxWritingModeItem* pModeItem = dynamic_cast< const SvxWritingModeItem* >( &GetObjectItem( SDRATTR_TEXTDIRECTION ) );
2050 return pModeItem && pModeItem->GetValue() == com::sun::star::text::WritingMode_TB_RL;
2055 void SdrTableObj::SetVerticalWriting(bool bVertical )
2057 if( bVertical != IsVerticalWriting() )
2059 SvxWritingModeItem aModeItem( com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION );
2060 SetObjectItem( aModeItem );
2066 WritingMode SdrTableObj::GetWritingMode() const
2068 SfxStyleSheet* pStyle = GetStyleSheet();
2069 if ( !pStyle )
2070 return WritingMode_LR_TB;
2072 WritingMode eWritingMode = WritingMode_LR_TB;
2073 const SfxItemSet &rSet = pStyle->GetItemSet();
2074 const SfxPoolItem *pItem;
2076 if ( rSet.GetItemState( SDRATTR_TEXTDIRECTION, false, &pItem ) == SfxItemState::SET )
2077 eWritingMode = static_cast< WritingMode >( static_cast< const SvxWritingModeItem * >( pItem )->GetValue() );
2079 if ( ( eWritingMode != WritingMode_TB_RL ) &&
2080 ( rSet.GetItemState( EE_PARA_WRITINGDIR, false, &pItem ) == SfxItemState::SET ) )
2082 if ( static_cast< const SvxFrameDirectionItem * >( pItem )->GetValue() == FRMDIR_HORI_LEFT_TOP )
2083 eWritingMode = WritingMode_LR_TB;
2084 else
2085 eWritingMode = WritingMode_RL_TB;
2088 return eWritingMode;
2093 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
2094 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
2095 bool SdrTableObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon ) const
2097 return SdrTextObj::TRGetBaseGeometry( rMatrix, rPolyPolygon );
2100 // sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
2101 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
2102 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
2103 void SdrTableObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon )
2105 SdrTextObj::TRSetBaseGeometry( rMatrix, rPolyPolygon );
2108 bool SdrTableObj::IsReallyEdited() const
2110 return pEdtOutl && pEdtOutl->IsModified();
2113 bool SdrTableObj::IsFontwork() const
2115 return false;
2118 sal_uInt32 SdrTableObj::GetHdlCount() const
2120 sal_uInt32 nCount = SdrTextObj::GetHdlCount();
2121 const sal_Int32 nRowCount = mpImpl->getRowCount();
2122 const sal_Int32 nColCount = mpImpl->getColumnCount();
2124 if( nRowCount && nColCount )
2125 nCount += nRowCount + nColCount + 2 + 1;
2127 return nCount;
2130 void SdrTableObj::AddToHdlList(SdrHdlList& rHdlList) const
2132 const sal_Int32 nRowCount = mpImpl->getRowCount();
2133 const sal_Int32 nColCount = mpImpl->getColumnCount();
2135 // first add row handles
2136 std::vector< TableEdgeHdl* > aRowEdges( nRowCount + 1 );
2138 for( sal_Int32 nRow = 0; nRow <= nRowCount; nRow++ )
2140 sal_Int32 nEdgeMin, nEdgeMax;
2141 const sal_Int32 nEdge = mpImpl->mpLayouter->getHorizontalEdge( nRow, &nEdgeMin, &nEdgeMax );
2142 nEdgeMin -= nEdge;
2143 nEdgeMax -= nEdge;
2145 Point aPoint( maRect.TopLeft() );
2146 aPoint.Y() += nEdge;
2148 TableEdgeHdl* pHdl= new TableEdgeHdl(aPoint,true,nEdgeMin,nEdgeMax,nColCount+1);
2149 pHdl->SetPointNum( nRow );
2150 rHdlList.AddHdl( pHdl );
2151 aRowEdges[nRow] = pHdl;
2154 // second add column handles
2155 std::vector< TableEdgeHdl* > aColEdges( nColCount + 1 );
2157 for( sal_Int32 nCol = 0; nCol <= nColCount; nCol++ )
2159 sal_Int32 nEdgeMin, nEdgeMax;
2160 const sal_Int32 nEdge = mpImpl->mpLayouter->getVerticalEdge( nCol, &nEdgeMin, &nEdgeMax );
2161 nEdgeMin -= nEdge;
2162 nEdgeMax -= nEdge;
2164 Point aPoint( maRect.TopLeft() );
2165 aPoint.X() += nEdge;
2167 TableEdgeHdl* pHdl = new TableEdgeHdl(aPoint,false,nEdgeMin,nEdgeMax, nRowCount+1);
2168 pHdl->SetPointNum( nCol );
2169 rHdlList.AddHdl( pHdl );
2170 aColEdges[nCol] = pHdl;
2173 // now add visible edges to row and column handles
2174 if( mpImpl->mpLayouter )
2176 TableLayouter& rLayouter = *mpImpl->mpLayouter;
2178 sal_Int32 nY = 0;
2180 for( sal_Int32 nRow = 0; nRow <= nRowCount; ++nRow )
2182 const sal_Int32 nRowHeight = (nRow == nRowCount) ? 0 : rLayouter.getRowHeight(nRow);
2183 sal_Int32 nX = 0;
2185 for( sal_Int32 nCol = 0; nCol <= nColCount; ++nCol )
2187 const sal_Int32 nColWidth = (nCol == nColCount) ? 0 : rLayouter.getColumnWidth(nCol);
2189 if( nRowHeight > 0 )
2191 if( rLayouter.isEdgeVisible( nCol, nRow, false ) )
2192 aColEdges[nCol]->SetEdge( nRow, nY, nY + nRowHeight, (rLayouter.getBorderLine( nCol, nRow, false ) == 0) ? Visible : Invisible);
2195 if( nColWidth > 0 )
2197 if( rLayouter.isEdgeVisible( nCol, nRow, true ) )
2198 aRowEdges[nRow]->SetEdge( nCol, nX, nX + nColWidth, (rLayouter.getBorderLine( nCol, nRow, true ) == 0) ? Visible : Invisible);
2201 nX += nColWidth;
2204 nY += nRowHeight;
2208 // add remaining handles
2209 SdrHdl* pH=0;
2210 rHdlList.AddHdl( pH = new TableBorderHdl( maRect, !IsTextEditActive() ) ); pH->SetMoveOutside( true );
2211 rHdlList.AddHdl( pH = new SdrHdl(maRect.TopLeft(),HDL_UPLFT) ); pH->SetMoveOutside( true );
2212 rHdlList.AddHdl( pH = new SdrHdl(maRect.TopCenter(),HDL_UPPER) ); pH->SetMoveOutside( true );
2213 rHdlList.AddHdl( pH = new SdrHdl(maRect.TopRight(),HDL_UPRGT) ); pH->SetMoveOutside( true );
2214 rHdlList.AddHdl( pH = new SdrHdl(maRect.LeftCenter(),HDL_LEFT) ); pH->SetMoveOutside( true );
2215 rHdlList.AddHdl( pH = new SdrHdl(maRect.RightCenter(),HDL_RIGHT) ); pH->SetMoveOutside( true );
2216 rHdlList.AddHdl( pH = new SdrHdl(maRect.BottomLeft(),HDL_LWLFT) ); pH->SetMoveOutside( true );
2217 rHdlList.AddHdl( pH = new SdrHdl(maRect.BottomCenter(),HDL_LOWER) ); pH->SetMoveOutside( true );
2218 rHdlList.AddHdl( pH = new SdrHdl(maRect.BottomRight(),HDL_LWRGT) ); pH->SetMoveOutside( true );
2220 const size_t nHdlCount = rHdlList.GetHdlCount();
2221 for( size_t nHdl = 0; nHdl < nHdlCount; ++nHdl )
2222 rHdlList.GetHdl(nHdl)->SetObj(const_cast<SdrTableObj*>(this));
2225 SdrHdl* SdrTableObj::GetHdl(sal_uInt32 nHdlNum) const
2227 // #i73248#
2228 // Warn the user that this is ineffective and show alternatives. Should not be used at all.
2229 OSL_FAIL("SdrTableObj::GetHdl(): ineffective, use AddToHdlList instead (!)");
2231 // to have an alternative, get single handle using the ineffective way
2232 SdrHdl* pRetval = 0;
2233 SdrHdlList aLocalList(0);
2234 AddToHdlList(aLocalList);
2235 const size_t nHdlCount(aLocalList.GetHdlCount());
2237 if(nHdlCount && static_cast<size_t>(nHdlNum) < nHdlCount)
2239 // remove and remember. The other created handles will be deleted again with the
2240 // destruction of the local list
2241 pRetval = aLocalList.RemoveHdl(nHdlNum);
2244 return pRetval;
2248 // Draging
2250 bool SdrTableObj::hasSpecialDrag() const
2252 return true;
2255 bool SdrTableObj::beginSpecialDrag(SdrDragStat& rDrag) const
2257 const SdrHdl* pHdl = rDrag.GetHdl();
2258 const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
2260 switch( eHdl )
2262 case HDL_UPLFT:
2263 case HDL_UPPER:
2264 case HDL_UPRGT:
2265 case HDL_LEFT:
2266 case HDL_RIGHT:
2267 case HDL_LWLFT:
2268 case HDL_LOWER:
2269 case HDL_LWRGT:
2270 case HDL_MOVE:
2272 break;
2275 case HDL_USER:
2277 rDrag.SetEndDragChangesAttributes(false);
2278 rDrag.SetNoSnap(true);
2279 break;
2282 default:
2284 return false;
2288 return true;
2291 bool SdrTableObj::applySpecialDrag(SdrDragStat& rDrag)
2293 bool bRet(true);
2294 const SdrHdl* pHdl = rDrag.GetHdl();
2295 const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
2297 switch( eHdl )
2299 case HDL_UPLFT:
2300 case HDL_UPPER:
2301 case HDL_UPRGT:
2302 case HDL_LEFT:
2303 case HDL_RIGHT:
2304 case HDL_LWLFT:
2305 case HDL_LOWER:
2306 case HDL_LWRGT:
2308 const Rectangle aNewRectangle(ImpDragCalcRect(rDrag));
2310 if (aNewRectangle != maRect)
2312 NbcSetLogicRect(aNewRectangle);
2315 break;
2318 case HDL_MOVE:
2320 NbcMove( Size( rDrag.GetDX(), rDrag.GetDY() ) );
2321 break;
2324 case HDL_USER:
2326 rDrag.SetEndDragChangesAttributes(false);
2327 rDrag.SetNoSnap(true);
2328 const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
2330 if( pEdgeHdl )
2332 if( GetModel() && IsInserted() )
2334 rDrag.SetEndDragChangesAttributes(true);
2337 mpImpl->DragEdge( pEdgeHdl->IsHorizontalEdge(), pEdgeHdl->GetPointNum(), pEdgeHdl->GetValidDragOffset( rDrag ) );
2339 break;
2342 default:
2344 bRet = false;
2348 return bRet;
2351 OUString SdrTableObj::getSpecialDragComment(const SdrDragStat& rDrag) const
2353 return SdrTextObj::getSpecialDragComment( rDrag );
2356 basegfx::B2DPolyPolygon SdrTableObj::getSpecialDragPoly(const SdrDragStat& rDrag) const
2358 basegfx::B2DPolyPolygon aRetval;
2359 const SdrHdl* pHdl = rDrag.GetHdl();
2361 if( pHdl && (HDL_USER == pHdl->GetKind()) )
2363 const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
2365 if( pEdgeHdl )
2367 aRetval = pEdgeHdl->getSpecialDragPoly( rDrag );
2371 return aRetval;
2375 // Create
2378 bool SdrTableObj::BegCreate(SdrDragStat& rStat)
2380 rStat.SetOrtho4Possible();
2381 Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
2382 aRect1.Justify();
2383 rStat.SetActionRect(aRect1);
2384 maRect = aRect1;
2385 return true;
2390 bool SdrTableObj::MovCreate(SdrDragStat& rStat)
2392 Rectangle aRect1;
2393 rStat.TakeCreateRect(aRect1);
2394 ImpJustifyRect(aRect1);
2395 rStat.SetActionRect(aRect1);
2396 maRect = aRect1; // fuer ObjName
2397 SetBoundRectDirty();
2398 bSnapRectDirty=true;
2399 return true;
2404 bool SdrTableObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
2406 rStat.TakeCreateRect(maRect);
2407 ImpJustifyRect(maRect);
2408 return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
2411 void SdrTableObj::BrkCreate(SdrDragStat& /*rStat*/)
2417 bool SdrTableObj::BckCreate(SdrDragStat& /*rStat*/)
2419 return true;
2424 basegfx::B2DPolyPolygon SdrTableObj::TakeCreatePoly(const SdrDragStat& rDrag) const
2426 Rectangle aRect1;
2427 rDrag.TakeCreateRect(aRect1);
2428 aRect1.Justify();
2430 basegfx::B2DPolyPolygon aRetval;
2431 const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom());
2432 aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
2433 return aRetval;
2438 Pointer SdrTableObj::GetCreatePointer() const
2440 return Pointer(PointerStyle::Cross);
2445 void SdrTableObj::createCell( CellRef& xNewCell )
2447 xNewCell = Cell::create( *this, 0 );
2452 SdrObjGeoData *SdrTableObj::NewGeoData() const
2454 return new TableObjectGeoData;
2459 void SdrTableObj::SaveGeoData(SdrObjGeoData& rGeo) const
2461 DBG_ASSERT( dynamic_cast< TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2462 SdrTextObj::SaveGeoData (rGeo);
2464 static_cast<TableObjectGeoData &>(rGeo).maLogicRect = maLogicRect;
2469 void SdrTableObj::RestGeoData(const SdrObjGeoData& rGeo)
2471 DBG_ASSERT( dynamic_cast< const TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2473 maLogicRect = static_cast<const TableObjectGeoData &>(rGeo).maLogicRect;
2475 SdrTextObj::RestGeoData (rGeo);
2477 if( mpImpl )
2478 mpImpl->LayoutTable(maRect, false, false);
2479 ActionChanged();
2484 SdrTableObj* SdrTableObj::CloneRange( const CellPos& rStart, const CellPos& rEnd )
2486 const sal_Int32 nColumns = rEnd.mnCol - rStart.mnCol + 1;
2487 const sal_Int32 nRows = rEnd.mnRow - rStart.mnRow + 1;
2489 SdrTableObj* pNewTableObj = new SdrTableObj( GetModel(), GetCurrentBoundRect(), nColumns, nRows);
2490 pNewTableObj->setTableStyleSettings( getTableStyleSettings() );
2491 pNewTableObj->setTableStyle( getTableStyle() );
2493 Reference< XTable > xTable( getTable() );
2494 Reference< XTable > xNewTable( pNewTableObj->getTable() );
2496 if( !xTable.is() || !xNewTable.is() )
2498 delete pNewTableObj;
2499 return 0;
2502 // copy cells
2503 for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
2505 for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol ) try
2507 CellRef xTargetCell( dynamic_cast< Cell* >( xNewTable->getCellByPosition( nCol, nRow ).get() ) );
2508 if( xTargetCell.is() )
2509 xTargetCell->cloneFrom( dynamic_cast< Cell* >( xTable->getCellByPosition( rStart.mnCol + nCol, rStart.mnRow + nRow ).get() ) );
2511 catch( Exception& )
2513 OSL_FAIL( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
2517 // copy row heights
2518 Reference< XTableRows > xNewRows( xNewTable->getRows(), UNO_QUERY_THROW );
2519 const OUString sHeight( "Height" );
2520 for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
2522 Reference< XPropertySet > xNewSet( xNewRows->getByIndex( nRow ), UNO_QUERY_THROW );
2523 xNewSet->setPropertyValue( sHeight, Any( mpImpl->mpLayouter->getRowHeight( rStart.mnRow + nRow ) ) );
2526 // copy column widths
2527 Reference< XTableColumns > xNewColumns( xNewTable->getColumns(), UNO_QUERY_THROW );
2528 const OUString sWidth( "Width" );
2529 for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol )
2531 Reference< XPropertySet > xNewSet( xNewColumns->getByIndex( nCol ), UNO_QUERY_THROW );
2532 xNewSet->setPropertyValue( sWidth, Any( mpImpl->mpLayouter->getColumnWidth( rStart.mnCol + nCol ) ) );
2535 pNewTableObj->NbcReformatText();
2536 pNewTableObj->SetLogicRect( pNewTableObj->GetCurrentBoundRect() );
2538 return pNewTableObj;
2543 void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 nLastColumn )
2545 if( mpImpl && mpImpl->mpLayouter )
2547 TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
2548 mpImpl->mpLayouter->DistributeColumns( maRect, nFirstColumn, nLastColumn );
2554 void SdrTableObj::DistributeRows( sal_Int32 nFirstRow, sal_Int32 nLastRow )
2556 if( mpImpl && mpImpl->mpLayouter )
2558 TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
2559 mpImpl->mpLayouter->DistributeRows( maRect, nFirstRow, nLastRow );
2565 void SdrTableObj::SetChanged()
2567 if( mpImpl )
2569 mpImpl->LayoutTable( maRect, false, false );
2572 ::SdrTextObj::SetChanged();
2577 void SdrTableObj::uno_lock()
2579 if( mpImpl && mpImpl->mxTable.is() )
2580 mpImpl->mxTable->lockBroadcasts();
2585 void SdrTableObj::uno_unlock()
2587 if( mpImpl && mpImpl->mxTable.is() )
2588 mpImpl->mxTable->unlockBroadcasts();
2597 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */