LibreOffice Module svx (master)  1
svdotable.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <memory>
21 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
22 #include <com/sun/star/container/XNamed.hpp>
23 #include <com/sun/star/container/XNameAccess.hpp>
24 #include <com/sun/star/container/XIndexAccess.hpp>
25 #include <unotools/configmgr.hxx>
26 #include <vcl/canvastools.hxx>
27 #include <vcl/ptrstyle.hxx>
28 #include <com/sun/star/style/XStyle.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <svl/style.hxx>
34 #include <editeng/editstat.hxx>
35 #include <editeng/outlobj.hxx>
37 #include <svx/svdmodel.hxx>
38 #include <svx/svdotable.hxx>
39 #include <svx/svdhdl.hxx>
41 #include <svx/svdoutl.hxx>
42 #include <svx/svddrag.hxx>
43 #include <tablemodel.hxx>
44 #include <cell.hxx>
45 #include "tablelayouter.hxx"
46 #include "tablehandles.hxx"
48 #include <svx/svdundo.hxx>
49 #include <svx/strings.hrc>
50 #include <svx/dialmgr.hxx>
52 #include <editeng/frmdiritem.hxx>
53 #include <cppuhelper/implbase.hxx>
54 #include <libxml/xmlwriter.h>
55 #include <rtl/ustrbuf.hxx>
56 
57 #include <boost/property_tree/ptree.hpp>
58 
59 using ::com::sun::star::uno::Any;
60 using ::com::sun::star::uno::Reference;
61 using ::com::sun::star::uno::UNO_QUERY;
62 using ::com::sun::star::uno::UNO_QUERY_THROW;
63 using ::com::sun::star::uno::Exception;
64 using ::com::sun::star::container::XIndexAccess;
65 using ::com::sun::star::style::XStyle;
66 using ::com::sun::star::table::XTableRows;
67 using ::com::sun::star::table::XTableColumns;
68 using ::com::sun::star::table::XTable;
70 using ::com::sun::star::util::XModifyBroadcaster;
73 using namespace ::com::sun::star;
74 using namespace ::com::sun::star::text;
75 using namespace ::com::sun::star::container;
76 using namespace ::com::sun::star::style;
77 
78 namespace sdr::table {
79 
80 namespace {
81 
82 class TableProperties : public TextProperties
83 {
84 protected:
85  // create a new itemset
86  std::unique_ptr<SfxItemSet> CreateObjectSpecificItemSet(SfxItemPool& rPool) override;
87 
88 public:
89  // basic constructor
90  explicit TableProperties(SdrObject& rObj );
91 
92  // constructor for copying, but using new object
93  TableProperties(const TableProperties& rProps, SdrObject& rObj );
94 
95  // Clone() operator, normally just calls the local copy constructor
96  std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
97 
98  virtual void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem = nullptr) override;
99 };
100 
101 }
102 
103 TableProperties::TableProperties(SdrObject& rObj)
104 : TextProperties(rObj)
105 {
106 }
107 
108 TableProperties::TableProperties(const TableProperties& rProps, SdrObject& rObj)
109 : TextProperties(rProps, rObj)
110 {
111 }
112 
113 std::unique_ptr<BaseProperties> TableProperties::Clone(SdrObject& rObj) const
114 {
115  return std::unique_ptr<BaseProperties>(new TableProperties(*this, rObj));
116 }
117 
118 void TableProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
119 {
120  if( nWhich == SDRATTR_TEXTDIRECTION )
121  AttributeProperties::ItemChange( nWhich, pNewItem );
122  else
123  TextProperties::ItemChange( nWhich, pNewItem );
124 }
125 
126 // create a new itemset
127 std::unique_ptr<SfxItemSet> TableProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
128 {
129  return std::make_unique<SfxItemSet>(rPool,
130 
131  // range from SdrAttrObj
135 
136  // range for SdrTableObj
138 
139  // range from SdrTextObj
141 }
142 
143 namespace {
144 
145 class TableObjectGeoData : public SdrTextObjGeoData
146 {
147 public:
149 };
150 
151 }
152 
153 TableStyleSettings::TableStyleSettings()
154 : mbUseFirstRow(true)
155 , mbUseLastRow(false)
156 , mbUseFirstColumn(false)
157 , mbUseLastColumn(false)
158 , mbUseRowBanding(true)
159 , mbUseColumnBanding(false)
160 {
161 }
162 
164 {
165  (*this) = rStyle;
166 }
167 
169 {
170  mbUseFirstRow = rStyle.mbUseFirstRow;
171  mbUseLastRow = rStyle.mbUseLastRow;
176  return *this;
177 }
178 
180 {
181  return
182  (mbUseFirstRow == rStyle.mbUseFirstRow) &&
183  (mbUseLastRow == rStyle.mbUseLastRow) &&
184  (mbUseFirstColumn == rStyle.mbUseFirstColumn) &&
185  (mbUseLastColumn == rStyle.mbUseLastColumn) &&
186  (mbUseRowBanding == rStyle.mbUseRowBanding) &&
188 }
189 
190 
191 class SdrTableObjImpl : public TableDesignUser, public ::cppu::WeakImplHelper< css::util::XModifyListener >
192 {
193 public:
197  std::unique_ptr<TableLayouter> mpLayouter;
200  Reference< XIndexAccess > mxTableStyle;
201  std::vector<std::unique_ptr<SdrUndoAction>> maUndos;
203 
204  void CropTableModelToSelection(const CellPos& rStart, const CellPos& rEnd);
205 
206  CellRef getCell( const CellPos& rPos ) const;
207  void LayoutTable( tools::Rectangle& rArea, bool bFitWidth, bool bFitHeight );
208 
209  void ApplyCellStyles();
210  void UpdateCells( tools::Rectangle const & rArea );
211 
212  SdrTableObjImpl();
213  virtual ~SdrTableObjImpl() override;
214 
215  void init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows );
216  void dispose();
217 
218  sal_Int32 getColumnCount() const;
220  std::vector<sal_Int32> getColumnWidths() const;
221  sal_Int32 getRowCount() const;
222 
223  void DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset );
224 
225  SdrTableObjImpl& operator=( const SdrTableObjImpl& rSource );
226 
227  // XModifyListener
228  virtual void SAL_CALL modified( const css::lang::EventObject& aEvent ) override;
229 
230  // XEventListener
231  virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
232 
233  void update();
234 
235  void connectTableStyle();
236  void disconnectTableStyle();
237  virtual bool isInUse() override;
238  void dumpAsXml(xmlTextWriterPtr pWriter) const;
239 private:
243  static bool lastLayoutFitWidth;
244  static bool lastLayoutFitHeight;
246  static sal_Int32 lastRowCount;
247  static sal_Int32 lastColCount;
248  static std::vector<sal_Int32> lastColWidths;
249 };
250 
259 std::vector<sal_Int32> SdrTableObjImpl::lastColWidths;
260 
262 : mpTableObj( nullptr )
263 , mbSkipChangeLayout(false)
264 {
265 }
266 
267 
269 {
270  if( lastLayoutTable == this )
271  lastLayoutTable = nullptr;
272 }
273 
274 
276 {
277  if(!mxTable.is())
278  {
279  return;
280  }
281 
282  const sal_Int32 nColumns(rEnd.mnCol - rStart.mnCol + 1);
283  const sal_Int32 nRows(rEnd.mnRow - rStart.mnRow + 1);
284 
285  if(nColumns < 1 || nRows < 1 || nColumns > getColumnCount() || nRows > getRowCount())
286  {
287  return;
288  }
289 
290  // tdf#116977 First thought was to create the new TableModel, copy data to it and then exchange
291  // mxTable and dispose old one. This does *not* work, even when all stuff looks nicely referenced
292  // and safe *because* Cell::create gets handed over the current SdrTableObj, hands it to
293  // ::Cell and there the local mxTable is initialized using rTableObj.getTable() (!). Due to This,
294  // the new created Cells in a new created TableModel based on given mpTableObj *will be disposed*
295  // when the old mxTable gets disposed - ARGH!
296  // To avoid, change strategy: Remember old TableModel, reset mxTable immediately - this is the
297  // SdrTableObjImpl of the current SdrTableObj anyways. Luckily, this works as intended...
298 
299  // remember old TableModel
300  TableModelRef xOldTable(mxTable);
301 
302  // immediately create new one and initialize. This creates ::Cell's which then will use
303  // the correct TableModel (accessed through SdrTableObj, but using local mxTable)
305  mxTable->init(nColumns, nRows);
306 
307  // copy cells
308  for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
309  {
310  for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol ) try
311  {
312  CellRef xTargetCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
313  if( xTargetCell.is() )
314  xTargetCell->cloneFrom( dynamic_cast< Cell* >( xOldTable->getCellByPosition( rStart.mnCol + nCol, rStart.mnRow + nRow ).get() ) );
315  }
316  catch( Exception& )
317  {
318  OSL_FAIL( "SdrTableObj::CropTableModelToSelection(), exception caught!" );
319  }
320  }
321 
322  // copy row heights
323  Reference< XTableRows > xNewRows(mxTable->getRows(), css::uno::UNO_SET_THROW );
324  const OUString sHeight( "Height" );
325  for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
326  {
327  Reference< XPropertySet > xNewSet( xNewRows->getByIndex( nRow ), UNO_QUERY_THROW );
328  xNewSet->setPropertyValue( sHeight, Any( mpLayouter->getRowHeight( rStart.mnRow + nRow ) ) );
329  }
330 
331  // copy column widths
332  Reference< XTableColumns > xNewColumns( mxTable->getColumns(), css::uno::UNO_SET_THROW );
333  const OUString sWidth( "Width" );
334  for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol )
335  {
336  Reference< XPropertySet > xNewSet( xNewColumns->getByIndex( nCol ), UNO_QUERY_THROW );
337  xNewSet->setPropertyValue( sWidth, Any( mpLayouter->getColumnWidth( rStart.mnCol + nCol ) ) );
338  }
339 
340  // reset layouter which still holds a copy to old TableModel
341  mpLayouter.reset();
342 
343  // cleanup old TableModel
344  {
345  Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
346  xOldTable->removeModifyListener( xListener );
347  xOldTable->dispose();
348  xOldTable.clear();
349  }
350 
351  // create and hand over to new TableLayouter
352  mpLayouter.reset(new TableLayouter( mxTable ));
353 
354  // add needed listener to react on changes
355  Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
356  mxTable->addModifyListener( xListener );
357 
358  // Apply Style to Cells
359  ApplyCellStyles();
360 
361  // layout cropped table
362  LayoutTable( mpTableObj->maRect, false, false );
363 }
364 
365 void SdrTableObjImpl::init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows )
366 {
367  mpTableObj = pTable;
368  mxTable = new TableModel( pTable );
369  mxTable->init( nColumns, nRows );
370  Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
371  mxTable->addModifyListener( xListener );
372  mpLayouter.reset(new TableLayouter( mxTable ));
373  LayoutTable( mpTableObj->maRect, true, true );
375 }
376 
377 
379 {
380  if(this == &rSource)
381  {
382  return *this;
383  }
384 
385  if(nullptr == mpTableObj || nullptr == rSource.mpTableObj)
386  {
387  // error: need both SdrObjects to successfully copy data
388  return *this;
389  }
390 
391  // remove evtl. listeners from local
393 
394  // reset layouter which holds a copy
395  mpLayouter.reset();
396 
397  // cleanup local mxTable if used
398  if( mxTable.is() )
399  {
400  Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
401  mxTable->removeModifyListener( xListener );
402  mxTable->dispose();
403  mxTable.clear();
404  }
405 
406  // tdf#127481: reset active cell reference
407  mxActiveCell.clear();
408 
409  // copy TableStyle (short internal data)
410  maTableStyle = rSource.maTableStyle;
411 
412  // create/copy new mxTable. This will copy all needed cells, too
413  mxTable = new TableModel( mpTableObj, rSource.mxTable );
414 
415  // create and hand over to new TableLayouter
416  mpLayouter.reset(new TableLayouter( mxTable ));
417 
418  // add needed listener to react on changes
419  Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
420  mxTable->addModifyListener( xListener );
421 
422  // handle TableStyle
423  Reference< XIndexAccess > xNewTableStyle;
424  SdrModel& rSourceSdrModel(rSource.mpTableObj->getSdrModelFromSdrObject());
425  SdrModel& rTargetSdrModel(mpTableObj->getSdrModelFromSdrObject());
426 
427  if(rSource.mxTableStyle.is() && &rSourceSdrModel == &rTargetSdrModel)
428  {
429  // source and target model the same -> keep current TableStyle
430  xNewTableStyle = rSource.mxTableStyle;
431  }
432 
433  if(!xNewTableStyle.is() && rSource.mxTableStyle.is()) try
434  {
435  // search in target SdrModel for that TableStyle
436  const OUString sStyleName( Reference< XNamed >( rSource.mxTableStyle, UNO_QUERY_THROW )->getName() );
437  Reference< XStyleFamiliesSupplier > xSFS(rTargetSdrModel.getUnoModel(), UNO_QUERY_THROW );
438  Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), css::uno::UNO_SET_THROW );
439  Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( "table" ), UNO_QUERY_THROW );
440 
441  if( xTableFamilyAccess->hasByName( sStyleName ) )
442  {
443  // found table style with the same name
444  xTableFamilyAccess->getByName( sStyleName ) >>= xNewTableStyle;
445  }
446  else
447  {
448  // copy or? Not found, use 1st existing TableStyle (or none)
449  Reference< XIndexAccess > xIndexAccess( xTableFamilyAccess, UNO_QUERY_THROW );
450  xIndexAccess->getByIndex( 0 ) >>= xNewTableStyle;
451  }
452  }
453  catch( Exception& )
454  {
455  OSL_FAIL("svx::SdrTableObjImpl::operator=(), exception caught!");
456  }
457 
458  // set that TableStyle
459  mxTableStyle = xNewTableStyle;
460 
461  // Apply Style to Cells
462  ApplyCellStyles();
463 
464  // copy geometry
466 
467  // layout cloned table
468  LayoutTable( mpTableObj->maRect, false, false );
469 
470  // re-connect to styles (evtl. in new SdrModel)
472 
473  return *this;
474 }
475 
477 {
478  if( !mxTable.is() || !mxTableStyle.is() )
479  return;
480 
481  const sal_Int32 nColCount = getColumnCount();
482  const sal_Int32 nRowCount = getRowCount();
483 
484  const TableStyleSettings& rStyle = maTableStyle;
485 
486  CellPos aPos;
487  for( aPos.mnRow = 0; aPos.mnRow < nRowCount; ++aPos.mnRow )
488  {
489  const bool bFirstRow = (aPos.mnRow == 0) && rStyle.mbUseFirstRow;
490  const bool bLastRow = (aPos.mnRow == nRowCount-1) && rStyle.mbUseLastRow;
491 
492  for( aPos.mnCol = 0; aPos.mnCol < nColCount; ++aPos.mnCol )
493  {
494  Reference< XStyle > xStyle;
495 
496  // first and last row win first, if used and available
497  if( bFirstRow )
498  {
499  mxTableStyle->getByIndex(first_row_style) >>= xStyle;
500  }
501  else if( bLastRow )
502  {
503  mxTableStyle->getByIndex(last_row_style) >>= xStyle;
504  }
505 
506  if( !xStyle.is() )
507  {
508  // next come first and last column, if used and available
509  if( rStyle.mbUseFirstColumn && (aPos.mnCol == 0) )
510  {
511  mxTableStyle->getByIndex(first_column_style) >>= xStyle;
512  }
513  else if( rStyle.mbUseLastColumn && (aPos.mnCol == nColCount-1) )
514  {
515  mxTableStyle->getByIndex(last_column_style) >>= xStyle;
516  }
517  }
518 
519  if( !xStyle.is() && rStyle.mbUseRowBanding )
520  {
521  if( (aPos.mnRow & 1) == 0 )
522  {
523  mxTableStyle->getByIndex(even_rows_style) >>= xStyle;
524  }
525  else
526  {
527  mxTableStyle->getByIndex(odd_rows_style) >>= xStyle;
528  }
529  }
530 
531  if( !xStyle.is() && rStyle.mbUseColumnBanding )
532  {
533  if( (aPos.mnCol & 1) == 0 )
534  {
535  mxTableStyle->getByIndex(even_columns_style) >>= xStyle;
536  }
537  else
538  {
539  mxTableStyle->getByIndex(odd_columns_style) >>= xStyle;
540  }
541  }
542 
543  if( !xStyle.is() )
544  {
545  // use default cell style if non found yet
546  mxTableStyle->getByIndex(body_style) >>= xStyle;
547  }
548 
549 
550  if( xStyle.is() )
551  {
553 
554  if( pStyle )
555  {
556  CellRef xCell( getCell( aPos ) );
557  if( xCell.is() && ( xCell->GetStyleSheet() != pStyle ) )
558  {
559  xCell->SetStyleSheet( pStyle, true );
560  }
561  }
562  }
563  }
564  }
565 }
566 
567 
569 {
571  mxTableStyle.clear();
572 
573  mpLayouter.reset();
574 
575  if( mxTable.is() )
576  {
577  Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
578  mxTable->removeModifyListener( xListener );
579  mxTable->dispose();
580  mxTable.clear();
581  }
582 }
583 
584 
585 void SdrTableObjImpl::DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset )
586 {
587  if( (nEdge >= 0) && mxTable.is()) try
588  {
589  const OUString sSize( "Size" );
590  if( mbHorizontal )
591  {
592  if (nEdge <= getRowCount())
593  {
594  sal_Int32 nHeight = mpLayouter->getRowHeight( (!nEdge)?nEdge:(nEdge-1) );
595  if(nEdge==0)
596  nHeight -= nOffset;
597  else
598  nHeight += nOffset;
599  Reference< XIndexAccess > xRows( mxTable->getRows(), UNO_QUERY_THROW );
600  Reference< XPropertySet > xRowSet( xRows->getByIndex( (!nEdge)?nEdge:(nEdge-1) ), UNO_QUERY_THROW );
601  xRowSet->setPropertyValue( sSize, Any( nHeight ) );
602  }
603  }
604  else
605  {
606  /*
607  fixes fdo#59889 and resizing of table in edge dragging
608  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
609  In LTR table vertical edge responsible for dragging of column x(x=0 to N-1) is, Edge x+1
610  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
611  In LTR table dragging of edge 0(for RTL table edge N) does nothing.
612  */
613  //Todo: Implement Dragging functionality for leftmost edge of table.
614  if (nEdge <= getColumnCount())
615  {
616  const bool bRTL = mpTableObj != nullptr && (mpTableObj->GetWritingMode() == WritingMode_RL_TB);
617  sal_Int32 nWidth;
618  if(bRTL)
619  {
620  nWidth = mpLayouter->getColumnWidth( nEdge );
621  }
622  else
623  {
624  nWidth = mpLayouter->getColumnWidth( (!nEdge)?nEdge:(nEdge-1) );
625  }
626  Reference< XIndexAccess > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
627  nWidth += nOffset;
628  if(bRTL && nEdge<getColumnCount())
629  {
630  Reference< XPropertySet > xColSet( xCols->getByIndex( nEdge ), UNO_QUERY_THROW );
631  xColSet->setPropertyValue( sSize, Any( nWidth ) );
632  }
633  else if(!bRTL && nEdge>0)
634  {
635  Reference< XPropertySet > xColSet( xCols->getByIndex( nEdge-1 ), UNO_QUERY_THROW );
636  xColSet->setPropertyValue( sSize, Any( nWidth ) );
637  }
638  /* To prevent the table resizing on edge dragging */
639  if( nEdge > 0 && nEdge < mxTable->getColumnCount() )
640  {
641  if( bRTL )
642  nEdge--;
643 
644  nWidth = mpLayouter->getColumnWidth(nEdge);
645  nWidth = std::max(static_cast<sal_Int32>(nWidth - nOffset), sal_Int32(0));
646 
647  Reference<XPropertySet> xColSet(xCols->getByIndex(nEdge), UNO_QUERY_THROW);
648  xColSet->setPropertyValue(sSize, Any(nWidth));
649  }
650  }
651  }
652  }
653  catch( Exception& )
654  {
655  OSL_FAIL( "svx::SdrTableObjImpl::DragEdge(), exception caught!" );
656  }
657 }
658 
659 
660 // XModifyListener
661 
662 
663 void SAL_CALL SdrTableObjImpl::modified( const css::lang::EventObject& /*aEvent*/ )
664 {
665  update();
666 }
667 
669 {
670  // source can be the table model itself or the assigned table template
671  TableModelNotifyGuard aGuard( mxTable.get() );
672  if( mpTableObj )
673  {
675  {
676  if(maEditPos.mnRow >= getRowCount())
678 
681 
683  }
684 
685  ApplyCellStyles();
686 
688  LayoutTable( mpTableObj->maRect, false, false );
689 
693  }
694 }
695 
696 
698 {
699  if( mxTableStyle.is() )
700  {
701  Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY );
702  if( xBroadcaster.is() )
703  {
704  Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
705  xBroadcaster->addModifyListener( xListener );
706  }
707  }
708 }
709 
710 
712 {
713  if( mxTableStyle.is() )
714  {
715  Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY );
716  if( xBroadcaster.is() )
717  {
718  Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
719  xBroadcaster->removeModifyListener( xListener );
720  }
721  }
722 }
723 
724 
726 {
727  return mpTableObj && mpTableObj->IsInserted();
728 }
729 
731 {
732  xmlTextWriterStartElement(pWriter, BAD_CAST("SdrTableObjImpl"));
733  if (mpLayouter)
734  mpLayouter->dumpAsXml(pWriter);
735  mxTable->dumpAsXml(pWriter);
736  xmlTextWriterEndElement(pWriter);
737 }
738 
739 
740 // XEventListener
741 
742 
743 void SAL_CALL SdrTableObjImpl::disposing( const css::lang::EventObject& /*Source*/ )
744 {
745  mxActiveCell.clear();
746  mxTable.clear();
747  mpLayouter.reset();
748  mpTableObj = nullptr;
749 }
750 
751 
753 {
754  CellRef xCell;
755  if( mxTable.is() ) try
756  {
757  xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
758  }
759  catch( Exception& )
760  {
761  OSL_FAIL( "svx::SdrTableObjImpl::getCell(), exception caught!" );
762  }
763  return xCell;
764 }
765 
766 
768 {
769  return mxTable.is() ? mxTable->getColumnCount() : 0;
770 }
771 
772 std::vector<sal_Int32> SdrTableObjImpl::getColumnWidths() const
773 {
774  std::vector<sal_Int32> aRet;
775 
776  if (mxTable.is())
777  aRet = mxTable->getColumnWidths();
778 
779  return aRet;
780 }
781 
783 {
784  return mxTable.is() ? mxTable->getRowCount() : 0;
785 }
786 
787 void SdrTableObjImpl::LayoutTable( tools::Rectangle& rArea, bool bFitWidth, bool bFitHeight )
788 {
790  return;
791  if(mpLayouter)
792  {
793  // Optimization: SdrTableObj::SetChanged() can call this very often, repeatedly
794  // with the same settings, noticeably increasing load time. Skip if already done.
795  bool bInteractiveMightGrowBecauseTextChanged =
797  WritingMode writingMode = mpTableObj->GetWritingMode();
798  if( bInteractiveMightGrowBecauseTextChanged
799  || lastLayoutTable != this || lastLayoutInputRectangle != rArea
800  || lastLayoutFitWidth != bFitWidth || lastLayoutFitHeight != bFitHeight
801  || lastLayoutMode != writingMode
802  || lastRowCount != getRowCount()
805  {
806  lastLayoutTable = this;
807  lastLayoutInputRectangle = rArea;
808  lastLayoutFitWidth = bFitWidth;
809  lastLayoutFitHeight = bFitHeight;
810  lastLayoutMode = writingMode;
813  // Column resize, when the total width and column count of the
814  // table is unchanged, but re-layout is still needed.
816  TableModelNotifyGuard aGuard( mxTable.get() );
817  mpLayouter->LayoutTable( rArea, bFitWidth, bFitHeight );
819  }
820  else
821  {
823  mpLayouter->UpdateBorderLayout();
824  }
825  }
826 }
827 
829 {
830  if( mpLayouter && mxTable.is() )
831  {
832  TableModelNotifyGuard aGuard( mxTable.get() );
833  mpLayouter->updateCells( rArea );
834  mxTable->setModified(true);
835  }
836 }
837 
838 
839 // BaseProperties section
840 
841 
842 std::unique_ptr<sdr::properties::BaseProperties> SdrTableObj::CreateObjectSpecificProperties()
843 {
844  return std::make_unique<TableProperties>(*this);
845 }
846 
847 
848 // DrawContact section
849 
850 
851 std::unique_ptr<sdr::contact::ViewContact> SdrTableObj::CreateObjectSpecificViewContact()
852 {
853  return std::make_unique<sdr::contact::ViewContactOfTableObj>(*this);
854 }
855 
857 : SdrTextObj(rSdrModel)
858 {
859  init( 1, 1 );
860 }
861 
863  SdrModel& rSdrModel,
864  const ::tools::Rectangle& rNewRect,
865  sal_Int32 nColumns,
866  sal_Int32 nRows)
867 : SdrTextObj(rSdrModel, rNewRect)
868  ,maLogicRect(rNewRect)
869 {
870  if( nColumns <= 0 )
871  nColumns = 1;
872 
873  if( nRows <= 0 )
874  nRows = 1;
875 
876  init( nColumns, nRows );
877 }
878 
879 
880 void SdrTableObj::init( sal_Int32 nColumns, sal_Int32 nRows )
881 {
882  bClosedObj = true;
883 
884  mpImpl = new SdrTableObjImpl;
885  mpImpl->init( this, nColumns, nRows );
886 
887  // Stuff done from old SetModel:
888  if( !maLogicRect.IsEmpty() )
889  {
891  mpImpl->LayoutTable( maRect, false, false );
892  }
893 }
894 
895 
897 {
898  mpImpl->dispose();
899 }
900 
901 
902 // table stuff
903 
904 
905 Reference< XTable > SdrTableObj::getTable() const
906 {
907  return Reference< XTable >( mpImpl->mxTable.get() );
908 }
909 
910 
911 bool SdrTableObj::isValid( const CellPos& rPos ) const
912 {
913  return (rPos.mnCol >= 0) && (rPos.mnCol < mpImpl->getColumnCount()) && (rPos.mnRow >= 0) && (rPos.mnRow < mpImpl->getRowCount());
914 }
915 
916 
918 {
919  return CellPos( 0,0 );
920 }
921 
922 
924 {
925  CellPos aPos;
926  if( mpImpl->mxTable.is() )
927  {
928  aPos.mnCol = mpImpl->getColumnCount()-1;
929  aPos.mnRow = mpImpl->getRowCount()-1;
930  }
931  return aPos;
932 }
933 
934 
935 CellPos SdrTableObj::getLeftCell( const CellPos& rPos, bool bEdgeTravel ) const
936 {
937  switch( GetWritingMode() )
938  {
939  default:
940  case WritingMode_LR_TB:
941  return getPreviousCell( rPos, bEdgeTravel );
942  case WritingMode_RL_TB:
943  return getNextCell( rPos, bEdgeTravel );
944  case WritingMode_TB_RL:
945  return getPreviousRow( rPos, bEdgeTravel );
946  }
947 }
948 
949 
950 CellPos SdrTableObj::getRightCell( const CellPos& rPos, bool bEdgeTravel ) const
951 {
952  switch( GetWritingMode() )
953  {
954  default:
955  case WritingMode_LR_TB:
956  return getNextCell( rPos, bEdgeTravel );
957  case WritingMode_RL_TB:
958  return getPreviousCell( rPos, bEdgeTravel );
959  case WritingMode_TB_RL:
960  return getNextRow( rPos, bEdgeTravel );
961  }
962 }
963 
964 
965 CellPos SdrTableObj::getUpCell( const CellPos& rPos, bool bEdgeTravel ) const
966 {
967  switch( GetWritingMode() )
968  {
969  default:
970  case WritingMode_LR_TB:
971  case WritingMode_RL_TB:
972  return getPreviousRow( rPos, bEdgeTravel );
973  case WritingMode_TB_RL:
974  return getPreviousCell( rPos, bEdgeTravel );
975  }
976 }
977 
978 
979 CellPos SdrTableObj::getDownCell( const CellPos& rPos, bool bEdgeTravel ) const
980 {
981  switch( GetWritingMode() )
982  {
983  default:
984  case WritingMode_LR_TB:
985  case WritingMode_RL_TB:
986  return getNextRow( rPos, bEdgeTravel );
987  case WritingMode_TB_RL:
988  return getNextCell( rPos, bEdgeTravel );
989  }
990 }
991 
992 
993 CellPos SdrTableObj::getPreviousCell( const CellPos& rPos, bool bEdgeTravel ) const
994 {
995  CellPos aPos( rPos );
996  if( mpImpl.is() )
997  {
998  CellRef xCell( mpImpl->getCell( aPos ) );
999  if( xCell.is() && xCell->isMerged() )
1000  {
1001  sal_Int32 nTemp = 0;
1002  findMergeOrigin( mpImpl->mxTable.get(), aPos.mnCol, aPos.mnRow, aPos.mnCol, nTemp );
1003  }
1004 
1005  if( aPos.mnCol > 0 )
1006  {
1007  --aPos.mnCol;
1008  }
1009 
1010  else if( bEdgeTravel && (aPos.mnRow > 0) )
1011  {
1012  aPos.mnCol = mpImpl->mxTable->getColumnCount()-1;
1013  --aPos.mnRow;
1014  }
1015  }
1016  return aPos;
1017 }
1018 
1019 
1020 CellPos SdrTableObj::getNextCell( const CellPos& rPos, bool bEdgeTravel ) const
1021 {
1022  CellPos aPos( rPos );
1023  if( mpImpl.is() )
1024  {
1025  CellRef xCell( mpImpl->getCell( aPos ) );
1026  if( xCell.is() )
1027  {
1028  if( xCell->isMerged() )
1029  {
1030  findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow );
1031 
1032  xCell = mpImpl->getCell(aPos);
1033 
1034  if( xCell.is() )
1035  {
1036  aPos.mnCol += xCell->getColumnSpan();
1037  aPos.mnRow = rPos.mnRow;
1038  }
1039  }
1040  else
1041  {
1042  aPos.mnCol += xCell->getColumnSpan();
1043  }
1044 
1045  if( aPos.mnCol < mpImpl->mxTable->getColumnCount() )
1046  return aPos;
1047 
1048  if( bEdgeTravel && ((aPos.mnRow + 1) < mpImpl->getRowCount()) )
1049  {
1050  aPos.mnCol = 0;
1051  aPos.mnRow += 1;
1052  return aPos;
1053  }
1054  }
1055  }
1056 
1057  // last cell reached, no traveling possible
1058  return rPos;
1059 }
1060 
1061 
1062 CellPos SdrTableObj::getPreviousRow( const CellPos& rPos, bool bEdgeTravel ) const
1063 {
1064  CellPos aPos( rPos );
1065  if( mpImpl.is() )
1066  {
1067  CellRef xCell( mpImpl->getCell( aPos ) );
1068  if( xCell.is() && xCell->isMerged() )
1069  {
1070  sal_Int32 nTemp = 0;
1071  findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, nTemp, aPos.mnRow );
1072  }
1073 
1074  if( aPos.mnRow > 0 )
1075  {
1076  --aPos.mnRow;
1077  }
1078  else if( bEdgeTravel && (aPos.mnCol > 0) )
1079  {
1080  aPos.mnRow = mpImpl->mxTable->getRowCount()-1;
1081  --aPos.mnCol;
1082  }
1083  }
1084  return aPos;
1085 }
1086 
1087 
1088 CellPos SdrTableObj::getNextRow( const CellPos& rPos, bool bEdgeTravel ) const
1089 {
1090  CellPos aPos( rPos );
1091 
1092  if( mpImpl.is() )
1093  {
1094  CellRef xCell( mpImpl->getCell( rPos ) );
1095  if( xCell.is() )
1096  {
1097  if( xCell->isMerged() )
1098  {
1099  findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow );
1100  xCell = mpImpl->getCell(aPos);
1101  aPos.mnCol = rPos.mnCol;
1102  }
1103 
1104  if( xCell.is() )
1105  aPos.mnRow += xCell->getRowSpan();
1106 
1107  if( aPos.mnRow < mpImpl->mxTable->getRowCount() )
1108  return aPos;
1109 
1110  if( bEdgeTravel && (aPos.mnCol + 1) < mpImpl->mxTable->getColumnCount() )
1111  {
1112  aPos.mnRow = 0;
1113  aPos.mnCol += 1;
1114 
1115  while( aPos.mnCol < mpImpl->mxTable->getColumnCount() )
1116  {
1117  xCell = mpImpl->getCell( aPos );
1118  if( xCell.is() && !xCell->isMerged() )
1119  return aPos;
1120  aPos.mnCol += 1;
1121  }
1122  }
1123  }
1124  }
1125 
1126  // last position reached, no more traveling possible
1127  return rPos;
1128 }
1129 
1130 
1132 {
1133  if( mpImpl.is())
1134  {
1135  return mpImpl->maTableStyle;
1136  }
1137  else
1138  {
1139  static TableStyleSettings aTmp;
1140  return aTmp;
1141  }
1142 }
1143 
1144 
1146 {
1147  if( mpImpl.is() )
1148  {
1149  mpImpl->maTableStyle = rStyle;
1150  mpImpl->update();
1151  }
1152 }
1153 
1154 
1155 TableHitKind SdrTableObj::CheckTableHit( const Point& rPos, sal_Int32& rnX, sal_Int32& rnY, const sal_uInt16 aTol ) const
1156 {
1157  if( !mpImpl.is() || !mpImpl->mxTable.is() )
1158  return TableHitKind::NONE;
1159 
1160  rnX = 0;
1161  rnY = 0;
1162 
1163  const sal_Int32 nColCount = mpImpl->getColumnCount();
1164  const sal_Int32 nRowCount = mpImpl->getRowCount();
1165 
1166  sal_Int32 nX = rPos.X() - maRect.Left();
1167  sal_Int32 nY = rPos.Y() - maRect.Top();
1168 
1169  if( (nX < 0) || (nX > maRect.GetWidth()) || (nY < 0) || (nY > maRect.GetHeight() ) )
1170  return TableHitKind::NONE;
1171 
1172  // get vertical edge number and check for a hit
1173  const bool bRTL = (GetWritingMode() == WritingMode_RL_TB);
1174  bool bVrtHit = false;
1175  if( !bRTL )
1176  {
1177  while( rnX <= nColCount )
1178  {
1179  if( nX - aTol <= 0 )
1180  {
1181  bVrtHit = true;
1182  break;
1183  }
1184 
1185  if( rnX == nColCount )
1186  break;
1187 
1188  nX -= mpImpl->mpLayouter->getColumnWidth( rnX );
1189  if( nX < 0 )
1190  break;
1191  rnX++;
1192  }
1193  }
1194  else
1195  {
1196  rnX = nColCount;
1197  while( rnX >= 0 )
1198  {
1199  if( nX - aTol <= 0 )
1200  {
1201  bVrtHit = true;
1202  break;
1203  }
1204 
1205  if( rnX == 0 )
1206  break;
1207 
1208  rnX--;
1209  nX -= mpImpl->mpLayouter->getColumnWidth( rnX );
1210  if( nX < 0 )
1211  break;
1212  }
1213  }
1214 
1215  // rnX is now the edge number left to the pointer, if it was hit bHrzHit is also true
1216 
1217  // get vertical edge number and check for a hit
1218  bool bHrzHit = false;
1219  while( rnY <= nRowCount )
1220  {
1221  if( nY - aTol <= 0 )
1222  {
1223  bHrzHit = true;
1224  break;
1225  }
1226 
1227  if( rnY == nRowCount )
1228  break;
1229 
1230  nY -= mpImpl->mpLayouter->getRowHeight(rnY);
1231  if( nY < 0 )
1232  break;
1233  rnY++;
1234  }
1235 
1236  // rnY is now the edge number above the pointer, if it was hit bVrtHit is also true
1237 
1238  if( bVrtHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, false ) )
1240 
1241  if( bHrzHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, true ) )
1243 
1244  CellRef xCell( mpImpl->getCell( CellPos( rnX, rnY ) ) );
1245  if( xCell.is() && xCell->isMerged() )
1246  findMergeOrigin( mpImpl->mxTable.get(), rnX, rnY, rnX, rnY );
1247 
1248  if( xCell.is() )
1249  {
1250  nX += mpImpl->mpLayouter->getColumnWidth( rnX );
1251  //Fix for fdo#62673 : non-editable cell in table on cell merge
1252  sal_Int32 i=0;
1253  while(xCell.is() && xCell->isMerged())
1254  {
1255  nX += mpImpl->mpLayouter->getColumnWidth( rnX+i );
1256  i++;
1257  if(rnX+i < nColCount)
1258  xCell=mpImpl->getCell( CellPos( rnX+i, rnY) );
1259  else
1260  break;
1261  }
1262 
1263  if( nX < xCell->GetTextLeftDistance() )
1264  return TableHitKind::Cell;
1265  }
1266 
1268 }
1269 
1271 {
1272  return getActiveCell()->GetItemSet();
1273 }
1274 
1275 void SdrTableObj::setTableStyle( const Reference< XIndexAccess >& xTableStyle )
1276 {
1277  if( mpImpl.is() && (mpImpl->mxTableStyle != xTableStyle) )
1278  {
1279  mpImpl->disconnectTableStyle();
1280  mpImpl->mxTableStyle = xTableStyle;
1281  mpImpl->connectTableStyle();
1282  mpImpl->update();
1283  }
1284 }
1285 
1286 
1287 const Reference< XIndexAccess >& SdrTableObj::getTableStyle() const
1288 {
1289  if( mpImpl.is() )
1290  {
1291  return mpImpl->mxTableStyle;
1292  }
1293  else
1294  {
1295  static Reference< XIndexAccess > aTmp;
1296  return aTmp;
1297  }
1298 }
1299 
1300 
1301 // text stuff
1302 
1303 
1306 {
1307  return dynamic_cast< SdrText* >( getActiveCell().get() );
1308 }
1309 
1310 
1312 SdrText* SdrTableObj::getText( sal_Int32 nIndex ) const
1313 {
1314  if( mpImpl->mxTable.is() )
1315  {
1316  const sal_Int32 nColCount = mpImpl->getColumnCount();
1317  if( nColCount )
1318  {
1319  CellPos aPos( nIndex % nColCount, nIndex / nColCount );
1320 
1321  CellRef xCell( mpImpl->getCell( aPos ) );
1322  return dynamic_cast< SdrText* >( xCell.get() );
1323  }
1324  }
1325  return nullptr;
1326 }
1327 
1328 
1330 sal_Int32 SdrTableObj::getTextCount() const
1331 {
1332  if( mpImpl->mxTable.is() )
1333  {
1334  const sal_Int32 nColCount = mpImpl->getColumnCount();
1335  const sal_Int32 nRowCount = mpImpl->getRowCount();
1336 
1337  return nColCount * nRowCount;
1338  }
1339  else
1340  {
1341  return 0;
1342  }
1343 }
1344 
1345 
1347 void SdrTableObj::setActiveText( sal_Int32 nIndex )
1348 {
1349  if( mpImpl.is() && mpImpl->mxTable.is() )
1350  {
1351  const sal_Int32 nColCount = mpImpl->mxTable->getColumnCount();
1352  if( nColCount )
1353  {
1354  CellPos aPos( nIndex % nColCount, nIndex / nColCount );
1355  if( isValid( aPos ) )
1356  setActiveCell( aPos );
1357  }
1358  }
1359 }
1360 
1361 
1363 sal_Int32 SdrTableObj::CheckTextHit(const Point& rPnt) const
1364 {
1365  if( mpImpl.is() && mpImpl->mxTable.is() )
1366  {
1367  CellPos aPos;
1368  if( CheckTableHit( rPnt, aPos.mnCol, aPos.mnRow ) == TableHitKind::CellTextArea )
1369  return aPos.mnRow * mpImpl->mxTable->getColumnCount() + aPos.mnCol;
1370  }
1371 
1372  return 0;
1373 }
1374 
1376 {
1377  if( mpImpl.is() && (mpImpl->getCell( mpImpl->maEditPos ).get() == &rCell) )
1378  return pEdtOutl;
1379  else
1380  return nullptr;
1381 }
1382 
1384 {
1385  assert(mpImpl.is() && mpImpl->mpLayouter && "getTableLayouter() error: no mpImpl or mpLayouter (!)");
1386  return *(mpImpl->mpLayouter);
1387 }
1388 
1390 {
1391  return true;
1392 }
1393 
1395 {
1396  return true;
1397 }
1398 
1400 {
1401  return true;
1402 }
1403 
1405 {
1406  return pEdtOutl && mpImpl.is() && (rPos == mpImpl->maEditPos);
1407 }
1408 
1409 
1411 {
1412  if( (pEditStatus->GetStatusWord() & EditStatusFlags::TextHeightChanged) && mpImpl.is() && mpImpl->mpLayouter )
1413  {
1414  tools::Rectangle aRect0( maRect );
1415  maRect = maLogicRect;
1416  mpImpl->LayoutTable( maRect, false, false );
1417  SetRectsDirty();
1418  ActionChanged();
1420  if (aRect0 != maRect)
1422  }
1423 }
1424 
1425 
1427 {
1428  rInfo.bResizeFreeAllowed=true;
1429  rInfo.bResizePropAllowed=true;
1430  rInfo.bRotateFreeAllowed=false;
1431  rInfo.bRotate90Allowed =false;
1432  rInfo.bMirrorFreeAllowed=false;
1433  rInfo.bMirror45Allowed =false;
1434  rInfo.bMirror90Allowed =false;
1435 
1436  // allow transparence
1437  rInfo.bTransparenceAllowed = true;
1438 
1439  rInfo.bShearAllowed =false;
1440  rInfo.bEdgeRadiusAllowed=false;
1441  rInfo.bCanConvToPath =false;
1442  rInfo.bCanConvToPoly =false;
1443  rInfo.bCanConvToPathLineToArea=false;
1444  rInfo.bCanConvToPolyLineToArea=false;
1445  rInfo.bCanConvToContour = false;
1446 }
1447 
1448 
1450 {
1451  return static_cast<sal_uInt16>(OBJ_TABLE);
1452 }
1453 
1454 void SdrTableObj::TakeTextRect( SdrOutliner& rOutliner, tools::Rectangle& rTextRect, bool bNoEditText, tools::Rectangle* pAnchorRect, bool /*bLineWidth*/ ) const
1455 {
1456  if( mpImpl.is() )
1457  TakeTextRect( mpImpl->maEditPos, rOutliner, rTextRect, bNoEditText, pAnchorRect );
1458 }
1459 
1460 
1461 void SdrTableObj::TakeTextRect( const CellPos& rPos, SdrOutliner& rOutliner, tools::Rectangle& rTextRect, bool bNoEditText, tools::Rectangle* pAnchorRect ) const
1462 {
1463  if( !mpImpl.is())
1464  return;
1465 
1466  CellRef xCell( mpImpl->getCell( rPos ) );
1467  if( !xCell.is() )
1468  return;
1469 
1470  tools::Rectangle aAnkRect;
1471  TakeTextAnchorRect( rPos, aAnkRect );
1472 
1473  SdrTextVertAdjust eVAdj=xCell->GetTextVerticalAdjust();
1474 
1475  EEControlBits nStat0=rOutliner.GetControlWord();
1476  nStat0 |= EEControlBits::AUTOPAGESIZE;
1477  rOutliner.SetControlWord(nStat0);
1478  rOutliner.SetMinAutoPaperSize(Size());
1479  rOutliner.SetMaxAutoPaperSize(aAnkRect.GetSize());
1480  rOutliner.SetPaperSize(aAnkRect.GetSize());
1481 
1482  // #103516# New try with _BLOCK for hor and ver after completely
1483  // supporting full width for vertical text.
1484 // if( SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
1485 // {
1486  rOutliner.SetMinAutoPaperSize(Size(aAnkRect.GetWidth(), 0));
1487 // }
1488 // else if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
1489 // {
1490 // rOutliner.SetMinAutoPaperSize(Size(0, aAnkRect.GetHeight()));
1491 // }
1492 
1493 
1494  // set text at outliner, maybe from edit outliner
1495  OutlinerParaObject* pPara= xCell->GetOutlinerParaObject();
1496  if (pEdtOutl && !bNoEditText && mpImpl->mxActiveCell == xCell )
1497  pPara=pEdtOutl->CreateParaObject().release();
1498 
1499  if (pPara)
1500  {
1501  const bool bHitTest(&getSdrModelFromSdrObject().GetHitTestOutliner() == &rOutliner);
1502  const SdrTextObj* pTestObj(rOutliner.GetTextObj());
1503 
1504  if( !pTestObj || !bHitTest || (pTestObj != this) || (pTestObj->GetOutlinerParaObject() != xCell->GetOutlinerParaObject()) )
1505  {
1506  if( bHitTest ) // #i33696# take back fix #i27510#
1507  rOutliner.SetTextObj( this );
1508 
1509  rOutliner.SetUpdateMode(true);
1510  rOutliner.SetText(*pPara);
1511  }
1512  }
1513  else
1514  {
1515  rOutliner.SetTextObj( nullptr );
1516  }
1517 
1518  if (pEdtOutl && !bNoEditText && pPara && mpImpl->mxActiveCell == xCell )
1519  delete pPara;
1520 
1521  rOutliner.SetUpdateMode(true);
1522  rOutliner.SetControlWord(nStat0);
1523 
1524  Point aTextPos(aAnkRect.TopLeft());
1525  Size aTextSiz(rOutliner.GetPaperSize());
1527  {
1528  long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
1529  if (eVAdj==SDRTEXTVERTADJUST_CENTER)
1530  aTextPos.AdjustY(nFreeHgt/2 );
1531  if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1532  aTextPos.AdjustY(nFreeHgt );
1533  }
1534 
1535  if (pAnchorRect)
1536  *pAnchorRect=aAnkRect;
1537 
1538  rTextRect=tools::Rectangle(aTextPos,aTextSiz);
1539 }
1540 
1541 
1543 {
1544  if( mpImpl.is() )
1545  {
1546  if( !mpImpl->mxActiveCell.is() )
1547  {
1548  CellPos aPos;
1549  const_cast< SdrTableObj* >(this)->setActiveCell( aPos );
1550  }
1551  return mpImpl->mxActiveCell;
1552  }
1553  else
1554  {
1555  static CellRef xCell;
1556  return xCell;
1557  }
1558 }
1559 
1560 
1562 {
1563  return mpImpl.is() ? mpImpl->getColumnCount() : 0;
1564 }
1565 
1566 sal_Int32 SdrTableObj::getRowCount() const
1567 {
1568  return mpImpl.is() ? mpImpl->getRowCount() : 0;
1569 }
1570 
1571 void SdrTableObj::changeEdge(bool bHorizontal, int nEdge, sal_Int32 nOffset)
1572 {
1573  if (mpImpl.is())
1574  mpImpl->DragEdge(bHorizontal, nEdge, nOffset);
1575 }
1576 
1578 {
1579  if( mpImpl.is() && mpImpl->mxTable.is() ) try
1580  {
1581  mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
1582  if( mpImpl->mxActiveCell.is() && mpImpl->mxActiveCell->isMerged() )
1583  {
1584  CellPos aOrigin;
1585  findMergeOrigin( mpImpl->mxTable.get(), rPos.mnCol, rPos.mnRow, aOrigin.mnCol, aOrigin.mnRow );
1586  mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( aOrigin.mnCol, aOrigin.mnRow ).get() ) );
1587  mpImpl->maEditPos = aOrigin;
1588  }
1589  else
1590  {
1591  mpImpl->maEditPos = rPos;
1592  }
1593  }
1594  catch( Exception& )
1595  {
1596  OSL_FAIL("SdrTableObj::setActiveCell(), exception caught!");
1597  }
1598 }
1599 
1600 
1602 {
1603  rPos = mpImpl->maEditPos;
1604 }
1605 
1606 
1607 void SdrTableObj::getCellBounds( const CellPos& rPos, ::tools::Rectangle& rCellRect )
1608 {
1609  if( mpImpl.is() )
1610  {
1611  CellRef xCell( mpImpl->getCell( rPos ) );
1612  if( xCell.is() )
1613  rCellRect = xCell->getCellRect();
1614  }
1615 }
1616 
1617 
1618 void SdrTableObj::TakeTextAnchorRect(tools::Rectangle& rAnchorRect) const
1619 {
1620  if( mpImpl.is() )
1621  TakeTextAnchorRect( mpImpl->maEditPos, rAnchorRect );
1622 }
1623 
1624 
1625 void SdrTableObj::TakeTextAnchorRect( const CellPos& rPos, tools::Rectangle& rAnchorRect ) const
1626 {
1627  tools::Rectangle aAnkRect(maRect);
1628 
1629  if( mpImpl.is() )
1630  {
1631  CellRef xCell( mpImpl->getCell( rPos ) );
1632  if( xCell.is() )
1633  xCell->TakeTextAnchorRect( aAnkRect );
1634  }
1635 
1636  ImpJustifyRect(aAnkRect);
1637  rAnchorRect=aAnkRect;
1638 }
1639 
1640 
1641 void SdrTableObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, tools::Rectangle* pViewInit, tools::Rectangle* pViewMin) const
1642 {
1643  if( mpImpl.is() )
1644  TakeTextEditArea( mpImpl->maEditPos, pPaperMin, pPaperMax, pViewInit, pViewMin );
1645 }
1646 
1647 
1648 void SdrTableObj::TakeTextEditArea( const CellPos& rPos, Size* pPaperMin, Size* pPaperMax, tools::Rectangle* pViewInit, tools::Rectangle* pViewMin ) const
1649 {
1650  Size aPaperMin,aPaperMax;
1651  tools::Rectangle aViewInit;
1652  TakeTextAnchorRect( rPos, aViewInit );
1653 
1654  Size aAnkSiz(aViewInit.GetSize());
1655  aAnkSiz.AdjustWidth( -1 ); aAnkSiz.AdjustHeight( -1 ); // because GetSize() increments by one
1656 
1657  Size aMaxSiz(aAnkSiz.Width(),1000000);
1658  Size aTmpSiz(getSdrModelFromSdrObject().GetMaxObjSize());
1659  if (aTmpSiz.Height()!=0)
1660  aMaxSiz.setHeight(aTmpSiz.Height() );
1661 
1662  CellRef xCell( mpImpl->getCell( rPos ) );
1663  SdrTextVertAdjust eVAdj = xCell.is() ? xCell->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_TOP;
1664 
1665  aPaperMax=aMaxSiz;
1666 
1667  aPaperMin.setWidth( aAnkSiz.Width() );
1668 
1669  if (pViewMin!=nullptr)
1670  {
1671  *pViewMin=aViewInit;
1672  long nYFree=aAnkSiz.Height()-aPaperMin.Height();
1673 
1674  if (eVAdj==SDRTEXTVERTADJUST_TOP)
1675  {
1676  pViewMin->AdjustBottom( -nYFree );
1677  }
1678  else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1679  {
1680  pViewMin->AdjustTop(nYFree );
1681  }
1682  else
1683  {
1684  pViewMin->AdjustTop(nYFree/2 );
1685  pViewMin->SetBottom(pViewMin->Top()+aPaperMin.Height() );
1686  }
1687  }
1688 
1689 
1690  if(IsVerticalWriting())
1691  aPaperMin.setWidth( 0 );
1692  else
1693  aPaperMin.setHeight( 0 );
1694 
1695  if (pPaperMin!=nullptr) *pPaperMin=aPaperMin;
1696  if (pPaperMax!=nullptr) *pPaperMax=aPaperMax;
1697  if (pViewInit!=nullptr) *pViewInit=aViewInit;
1698 }
1699 
1700 
1702 {
1703  EEAnchorMode eRet=EEAnchorMode::TopLeft;
1704  CellRef xCell( getActiveCell() );
1705  if( xCell.is() )
1706  {
1707  SdrTextVertAdjust eV=xCell->GetTextVerticalAdjust();
1708 
1709  {
1710  if (eV==SDRTEXTVERTADJUST_TOP)
1711  {
1712  eRet=EEAnchorMode::TopLeft;
1713  }
1714  else if (eV==SDRTEXTVERTADJUST_BOTTOM)
1715  {
1716  eRet=EEAnchorMode::BottomLeft;
1717  }
1718  else
1719  {
1720  eRet=EEAnchorMode::VCenterLeft;
1721  }
1722  }
1723  }
1724  return eRet;
1725 }
1726 
1727 
1729 {
1730  OUStringBuffer sName(SvxResId(STR_ObjNameSingulTable));
1731 
1732  OUString aName(GetName());
1733  if (!aName.isEmpty())
1734  {
1735  sName.append(' ');
1736  sName.append('\'');
1737  sName.append(aName);
1738  sName.append('\'');
1739  }
1740 
1741  return sName.makeStringAndClear();
1742 }
1743 
1744 
1746 {
1747  return SvxResId(STR_ObjNamePluralTable);
1748 }
1749 
1750 
1752 {
1753  return CloneHelper< SdrTableObj >(rTargetModel);
1754 }
1755 
1757 {
1758  if( this == &rObj )
1759  {
1760  return *this;
1761  }
1762 
1763  // call parent
1764  // before SdrObject::operator= was called which is wrong from
1765  // the derivation hierarchy and may leave quite some entries
1766  // uninitialized. Changed to SdrTextObj::operator=, but had to adapt
1767  // usage of pNewOutlinerParaObject/mpText there due to nullptr access
1768  SdrTextObj::operator=(rObj);
1769 
1770  TableModelNotifyGuard aGuard( mpImpl.is() ? mpImpl->mxTable.get() : nullptr );
1771 
1772  maLogicRect = rObj.maLogicRect;
1773  maRect = rObj.maRect;
1774  aGeo = rObj.aGeo;
1775  eTextKind = rObj.eTextKind;
1776  bTextFrame = rObj.bTextFrame;
1777  aTextSize = rObj.aTextSize;
1779  bNoShear = rObj.bNoShear;
1781 
1782  // use SdrTableObjImpl::operator= now to
1783  // copy model data and other stuff (see there)
1784  *mpImpl = *rObj.mpImpl;
1785 
1786  return *this;
1787 }
1788 
1789 
1791 {
1792  return maRect;
1793 }
1794 
1795 
1797 {
1798  NbcSetLogicRect( rRect );
1799 }
1800 
1801 
1803 {
1804  return maLogicRect;
1805 }
1806 
1807 
1809 {
1810 }
1811 
1812 
1814 {
1815  if( pEdtOutl != nullptr )
1816  return false;
1817 
1818  pEdtOutl=&rOutl;
1819 
1820  mbInEditMode = true;
1821 
1822  rOutl.Init( OutlinerMode::TextObject );
1823  rOutl.SetRefDevice(getSdrModelFromSdrObject().GetRefDevice());
1824 
1825  bool bUpdateMode=rOutl.GetUpdateMode();
1826  if (bUpdateMode) rOutl.SetUpdateMode(false);
1827  Size aPaperMin;
1828  Size aPaperMax;
1829  tools::Rectangle aEditArea;
1830  TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,nullptr);
1831 
1832  rOutl.SetMinAutoPaperSize(aPaperMin);
1833  rOutl.SetMaxAutoPaperSize(aPaperMax);
1834  rOutl.SetPaperSize(aPaperMax);
1835 
1836  if (bUpdateMode) rOutl.SetUpdateMode(true);
1837 
1838  EEControlBits nStat=rOutl.GetControlWord();
1839  nStat |= EEControlBits::AUTOPAGESIZE;
1840  nStat &=~EEControlBits::STRETCHING;
1841  rOutl.SetControlWord(nStat);
1842 
1844  if(pPara)
1845  rOutl.SetText(*pPara);
1846 
1847  rOutl.UpdateFields();
1848  rOutl.ClearModifyFlag();
1849 
1850  return true;
1851 }
1852 
1853 
1855 {
1856 
1857  if (getSdrModelFromSdrObject().IsUndoEnabled() && !mpImpl->maUndos.empty())
1858  {
1859  // These actions should be on the undo stack after text edit.
1860  for (std::unique_ptr<SdrUndoAction>& pAction : mpImpl->maUndos)
1861  getSdrModelFromSdrObject().AddUndo( std::move(pAction));
1862  mpImpl->maUndos.clear();
1863 
1864  getSdrModelFromSdrObject().AddUndo(getSdrModelFromSdrObject().GetSdrUndoFactory().CreateUndoGeoObject(*this));
1865  }
1866 
1867  if(rOutl.IsModified())
1868  {
1869  std::unique_ptr<OutlinerParaObject> pNewText;
1870  Paragraph* p1stPara = rOutl.GetParagraph( 0 );
1871  sal_Int32 nParaCnt = rOutl.GetParagraphCount();
1872 
1873  if(p1stPara)
1874  {
1875  // to remove the grey field background
1876  rOutl.UpdateFields();
1877 
1878  // create new text object
1879  pNewText = rOutl.CreateParaObject( 0, nParaCnt );
1880  }
1881  SetOutlinerParaObject(std::move(pNewText));
1882  }
1883 
1884  pEdtOutl = nullptr;
1885  rOutl.Clear();
1886  EEControlBits nStat = rOutl.GetControlWord();
1887  nStat &= ~EEControlBits::AUTOPAGESIZE;
1888  rOutl.SetControlWord(nStat);
1889 
1890  mbInEditMode = false;
1891 }
1892 
1893 
1895 {
1896  CellRef xCell( getActiveCell() );
1897  if( xCell.is() )
1898  return xCell->GetOutlinerParaObject();
1899  else
1900  return nullptr;
1901 }
1902 
1903 
1904 void SdrTableObj::NbcSetOutlinerParaObject( std::unique_ptr<OutlinerParaObject> pTextObject)
1905 {
1906  CellRef xCell( getActiveCell() );
1907  if( xCell.is() )
1908  {
1909  // Update HitTestOutliner
1910  const SdrTextObj* pTestObj(getSdrModelFromSdrObject().GetHitTestOutliner().GetTextObj());
1911 
1912  if(pTestObj && pTestObj->GetOutlinerParaObject() == xCell->GetOutlinerParaObject())
1913  {
1915  }
1916 
1917  xCell->SetOutlinerParaObject( std::move(pTextObject) );
1918  SetTextSizeDirty();
1920  }
1921 }
1922 
1923 
1925 {
1926  maLogicRect=rRect;
1928  const bool bWidth = maLogicRect.getWidth() != maRect.getWidth();
1929  const bool bHeight = maLogicRect.getHeight() != maRect.getHeight();
1930  maRect = maLogicRect;
1931  if (mpImpl->mbSkipChangeLayout)
1932  // Avoid distributing newly available space between existing cells.
1934  else
1935  NbcAdjustTextFrameWidthAndHeight(!bHeight, !bWidth);
1936  SetRectsDirty();
1937 }
1938 
1939 
1940 void SdrTableObj::AdjustToMaxRect( const tools::Rectangle& rMaxRect, bool /* bShrinkOnly = false */ )
1941 {
1942  tools::Rectangle aAdjustRect( rMaxRect );
1943  aAdjustRect.setHeight( GetLogicRect().getHeight() );
1944  SetLogicRect( aAdjustRect );
1945 }
1946 
1947 
1948 void SdrTableObj::NbcMove(const Size& rSiz)
1949 {
1950  maLogicRect.Move(rSiz);
1951  SdrTextObj::NbcMove( rSiz );
1952  if( mpImpl.is() )
1953  mpImpl->UpdateCells( maRect );
1954 }
1955 
1956 
1957 void SdrTableObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1958 {
1959  tools::Rectangle aOldRect( maLogicRect );
1960  ResizeRect(maLogicRect,rRef,xFact,yFact);
1961 
1962  maRect = maLogicRect;
1964  SetRectsDirty();
1965 }
1966 
1967 
1969 {
1970  tools::Rectangle aNewRect(maLogicRect);
1971  bool bRet=AdjustTextFrameWidthAndHeight(aNewRect);
1972  if (bRet)
1973  {
1974  tools::Rectangle aBoundRect0;
1975  if (pUserCall!=nullptr)
1976  aBoundRect0=GetLastBoundRect();
1977  maRect = aNewRect;
1978  SetRectsDirty();
1979  SetChanged();
1982  }
1983  return bRet;
1984 }
1985 
1986 
1987 bool SdrTableObj::AdjustTextFrameWidthAndHeight(tools::Rectangle& rR, bool bHeight, bool bWidth) const
1988 {
1989  if(rR.IsEmpty() || !mpImpl.is() || !mpImpl->mxTable.is())
1990  return false;
1991 
1992  tools::Rectangle aRectangle( rR );
1993  mpImpl->LayoutTable( aRectangle, !bWidth, !bHeight );
1994 
1995  if( aRectangle != rR )
1996  {
1997  rR = aRectangle;
1998  return true;
1999  }
2000  else
2001  {
2002  return false;
2003  }
2004 }
2005 
2006 
2008 {
2010 }
2011 
2012 
2014 {
2016  return rModeItem.GetValue() == css::text::WritingMode_TB_RL;
2017 }
2018 
2019 
2021 {
2022  if(bVertical != IsVerticalWriting() )
2023  {
2024  SvxWritingModeItem aModeItem( css::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION );
2025  SetObjectItem( aModeItem );
2026  }
2027 }
2028 
2029 
2031 {
2032  SfxStyleSheet* pStyle = GetStyleSheet();
2033  if ( !pStyle )
2034  return WritingMode_LR_TB;
2035 
2036  WritingMode eWritingMode = WritingMode_LR_TB;
2037  const SfxItemSet &rSet = pStyle->GetItemSet();
2038  const SfxPoolItem *pItem;
2039 
2040  if ( rSet.GetItemState( SDRATTR_TEXTDIRECTION, false, &pItem ) == SfxItemState::SET )
2041  eWritingMode = static_cast< const SvxWritingModeItem * >( pItem )->GetValue();
2042 
2043  if ( ( eWritingMode != WritingMode_TB_RL ) &&
2044  ( rSet.GetItemState( EE_PARA_WRITINGDIR, false, &pItem ) == SfxItemState::SET ) )
2045  {
2046  if ( static_cast< const SvxFrameDirectionItem * >( pItem )->GetValue() == SvxFrameDirection::Horizontal_LR_TB )
2047  eWritingMode = WritingMode_LR_TB;
2048  else
2049  eWritingMode = WritingMode_RL_TB;
2050  }
2051 
2052  return eWritingMode;
2053 }
2054 
2056 {
2057  mpImpl->maUndos.push_back(std::unique_ptr<SdrUndoAction>(pUndo));
2058 }
2059 
2060 void SdrTableObj::SetSkipChangeLayout(bool bSkipChangeLayout)
2061 {
2062  mpImpl->mbSkipChangeLayout = bSkipChangeLayout;
2063 }
2064 
2066 {
2067  return pEdtOutl && pEdtOutl->IsModified();
2068 }
2069 
2071 {
2072  return false;
2073 }
2074 
2075 sal_uInt32 SdrTableObj::GetHdlCount() const
2076 {
2077  sal_uInt32 nCount = SdrTextObj::GetHdlCount();
2078  const sal_Int32 nRowCount = mpImpl->getRowCount();
2079  const sal_Int32 nColCount = mpImpl->getColumnCount();
2080 
2081  if( nRowCount && nColCount )
2082  nCount += nRowCount + nColCount + 2 + 1;
2083 
2084  return nCount;
2085 }
2086 
2088 {
2089  const sal_Int32 nRowCount = mpImpl->getRowCount();
2090  const sal_Int32 nColCount = mpImpl->getColumnCount();
2091 
2092  // first add row handles
2093  std::vector<TableEdgeHdl*> aRowEdges(nRowCount + 1);
2094  for (auto const & rEdge : mpImpl->mpLayouter->getHorizontalEdges())
2095  {
2096  Point aPoint(maRect.TopLeft());
2097  aPoint.AdjustY(rEdge.nPosition);
2098 
2099  std::unique_ptr<TableEdgeHdl> pHdl(new TableEdgeHdl(aPoint, true, rEdge.nMin, rEdge.nMax, nColCount + 1));
2100  pHdl->SetPointNum(rEdge.nIndex);
2101  aRowEdges[rEdge.nIndex] = pHdl.get();
2102  rHdlList.AddHdl(std::move(pHdl));
2103  }
2104 
2105  // second add column handles
2106  std::vector<TableEdgeHdl*> aColEdges(nColCount + 1);
2107  for (auto const & rEdge : mpImpl->mpLayouter->getVerticalEdges())
2108  {
2109  Point aPoint(maRect.TopLeft());
2110  aPoint.AdjustX(rEdge.nPosition);
2111 
2112  std::unique_ptr<TableEdgeHdl> pHdl(new TableEdgeHdl(aPoint, false, rEdge.nMin, rEdge.nMax, nRowCount + 1));
2113  pHdl->SetPointNum(rEdge.nIndex);
2114  aColEdges[rEdge.nIndex] = pHdl.get();
2115  rHdlList.AddHdl(std::move(pHdl));
2116  }
2117 
2118  // now add visible edges to row and column handles
2119  if( mpImpl->mpLayouter )
2120  {
2121  TableLayouter& rLayouter = *mpImpl->mpLayouter;
2122 
2123  sal_Int32 nY = 0;
2124 
2125  for( sal_Int32 nRow = 0; nRow <= nRowCount; ++nRow )
2126  {
2127  const sal_Int32 nRowHeight = (nRow == nRowCount) ? 0 : rLayouter.getRowHeight(nRow);
2128  sal_Int32 nX = 0;
2129 
2130  for( sal_Int32 nCol = 0; nCol <= nColCount; ++nCol )
2131  {
2132  const sal_Int32 nColWidth = (nCol == nColCount) ? 0 : rLayouter.getColumnWidth(nCol);
2133 
2134  if( nRowHeight > 0 )
2135  {
2136  if( rLayouter.isEdgeVisible( nCol, nRow, false ) )
2137  aColEdges[nCol]->SetEdge( nRow, nY, nY + nRowHeight, (rLayouter.getBorderLine( nCol, nRow, false ) == nullptr) ? Visible : Invisible);
2138  }
2139 
2140  if( nColWidth > 0 )
2141  {
2142  if( rLayouter.isEdgeVisible( nCol, nRow, true ) )
2143  aRowEdges[nRow]->SetEdge( nCol, nX, nX + nColWidth, (rLayouter.getBorderLine( nCol, nRow, true ) == nullptr) ? Visible : Invisible);
2144  }
2145 
2146  nX += nColWidth;
2147  }
2148 
2149  nY += nRowHeight;
2150  }
2151  }
2152 
2153  // add remaining handles
2154  SdrHdlList tempList(nullptr);
2155  tempList.AddHdl( std::make_unique<TableBorderHdl>( maRect, !IsTextEditActive() ) );
2156  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.TopLeft(),SdrHdlKind::UpperLeft) );
2157  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.TopCenter(),SdrHdlKind::Upper) );
2158  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.TopRight(),SdrHdlKind::UpperRight) );
2159  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.LeftCenter(),SdrHdlKind::Left) );
2160  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.RightCenter(),SdrHdlKind::Right) );
2161  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.BottomLeft(),SdrHdlKind::LowerLeft) );
2162  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.BottomCenter(),SdrHdlKind::Lower) );
2163  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.BottomRight(),SdrHdlKind::LowerRight) );
2164  for( size_t nHdl = 0; nHdl < tempList.GetHdlCount(); ++nHdl )
2165  tempList.GetHdl(nHdl)->SetMoveOutside(true);
2166  tempList.MoveTo(rHdlList);
2167 
2168  const size_t nHdlCount = rHdlList.GetHdlCount();
2169  for( size_t nHdl = 0; nHdl < nHdlCount; ++nHdl )
2170  rHdlList.GetHdl(nHdl)->SetObj(const_cast<SdrTableObj*>(this));
2171 }
2172 
2173 // Dragging
2174 
2176 {
2177  return true;
2178 }
2179 
2181 {
2182  const SdrHdl* pHdl = rDrag.GetHdl();
2183  const SdrHdlKind eHdl((pHdl == nullptr) ? SdrHdlKind::Move : pHdl->GetKind());
2184 
2185  switch( eHdl )
2186  {
2187  case SdrHdlKind::UpperLeft:
2188  case SdrHdlKind::Upper:
2190  case SdrHdlKind::Left:
2191  case SdrHdlKind::Right:
2192  case SdrHdlKind::LowerLeft:
2193  case SdrHdlKind::Lower:
2195  case SdrHdlKind::Move:
2196  {
2197  break;
2198  }
2199 
2200  case SdrHdlKind::User:
2201  {
2202  rDrag.SetEndDragChangesAttributes(false);
2203  rDrag.SetNoSnap();
2204  break;
2205  }
2206 
2207  default:
2208  {
2209  return false;
2210  }
2211  }
2212 
2213  return true;
2214 }
2215 
2217 {
2218  bool bRet(true);
2219  const SdrHdl* pHdl = rDrag.GetHdl();
2220  const SdrHdlKind eHdl((pHdl == nullptr) ? SdrHdlKind::Move : pHdl->GetKind());
2221 
2222  switch( eHdl )
2223  {
2224  case SdrHdlKind::UpperLeft:
2225  case SdrHdlKind::Upper:
2227  case SdrHdlKind::Left:
2228  case SdrHdlKind::Right:
2229  case SdrHdlKind::LowerLeft:
2230  case SdrHdlKind::Lower:
2232  {
2233  const tools::Rectangle aNewRectangle(ImpDragCalcRect(rDrag));
2234 
2235  if (aNewRectangle != maRect)
2236  {
2237  NbcSetLogicRect(aNewRectangle);
2238  }
2239 
2240  break;
2241  }
2242 
2243  case SdrHdlKind::Move:
2244  {
2245  NbcMove( Size( rDrag.GetDX(), rDrag.GetDY() ) );
2246  break;
2247  }
2248 
2249  case SdrHdlKind::User:
2250  {
2251  rDrag.SetEndDragChangesAttributes(false);
2252  rDrag.SetNoSnap();
2253  const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
2254 
2255  if( pEdgeHdl )
2256  {
2257  if( IsInserted() )
2258  {
2259  rDrag.SetEndDragChangesAttributes(true);
2260  rDrag.SetEndDragChangesLayout(true);
2261  }
2262 
2263  mpImpl->DragEdge( pEdgeHdl->IsHorizontalEdge(), pEdgeHdl->GetPointNum(), pEdgeHdl->GetValidDragOffset( rDrag ) );
2264  }
2265  break;
2266  }
2267 
2268  default:
2269  {
2270  bRet = false;
2271  }
2272  }
2273 
2274  return bRet;
2275 }
2276 
2278 {
2279  basegfx::B2DPolyPolygon aRetval;
2280  const SdrHdl* pHdl = rDrag.GetHdl();
2281 
2282  if( pHdl && (SdrHdlKind::User == pHdl->GetKind()) )
2283  {
2284  const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
2285 
2286  if( pEdgeHdl )
2287  {
2288  aRetval = pEdgeHdl->getSpecialDragPoly( rDrag );
2289  }
2290  }
2291 
2292  return aRetval;
2293 }
2294 
2295 
2296 // Create
2297 
2298 
2300 {
2301  rStat.SetOrtho4Possible();
2302  tools::Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
2303  aRect1.Justify();
2304  rStat.SetActionRect(aRect1);
2305  maRect = aRect1;
2306  return true;
2307 }
2308 
2309 
2311 {
2312  tools::Rectangle aRect1;
2313  rStat.TakeCreateRect(aRect1);
2314  ImpJustifyRect(aRect1);
2315  rStat.SetActionRect(aRect1);
2316  maRect = aRect1; // for ObjName
2318  bSnapRectDirty=true;
2319  return true;
2320 }
2321 
2322 
2324 {
2325  rStat.TakeCreateRect(maRect);
2327  return (eCmd==SdrCreateCmd::ForceEnd || rStat.GetPointCount()>=2);
2328 }
2329 
2331 {
2332 }
2333 
2334 
2336 {
2337  return true;
2338 }
2339 
2340 
2342 {
2343  tools::Rectangle aRect1;
2344  rDrag.TakeCreateRect(aRect1);
2345  aRect1.Justify();
2346 
2347  basegfx::B2DPolyPolygon aRetval;
2350  return aRetval;
2351 }
2352 
2353 
2355 {
2356  return PointerStyle::Cross;
2357 }
2358 
2359 
2361 {
2362  xNewCell = Cell::create( *this );
2363 }
2364 
2365 
2367 {
2368  return new TableObjectGeoData;
2369 }
2370 
2371 
2373 {
2374  DBG_ASSERT( dynamic_cast< TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2375  SdrTextObj::SaveGeoData (rGeo);
2376 
2377  static_cast<TableObjectGeoData &>(rGeo).maLogicRect = maLogicRect;
2378 }
2379 
2380 
2382 {
2383  DBG_ASSERT( dynamic_cast< const TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2384 
2385  maLogicRect = static_cast<const TableObjectGeoData &>(rGeo).maLogicRect;
2386 
2387  SdrTextObj::RestGeoData (rGeo);
2388 
2389  if( mpImpl.is() )
2390  mpImpl->LayoutTable(maRect, false, false);
2391  ActionChanged();
2392 }
2393 
2395 {
2396  if(!mpImpl.is())
2397  {
2398  return;
2399  }
2400 
2401  mpImpl->CropTableModelToSelection(rStart, rEnd);
2402 }
2403 
2404 void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 nLastColumn, const bool bOptimize, const bool bMinimize )
2405 {
2406  if( mpImpl.is() && mpImpl->mpLayouter )
2407  {
2408  TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
2409  mpImpl->mpLayouter->DistributeColumns( maRect, nFirstColumn, nLastColumn, bOptimize, bMinimize );
2410  }
2411 }
2412 
2413 
2414 void SdrTableObj::DistributeRows( sal_Int32 nFirstRow, sal_Int32 nLastRow, const bool bOptimize, const bool bMinimize )
2415 {
2416  if( mpImpl.is() && mpImpl->mpLayouter )
2417  {
2418  TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
2419  mpImpl->mpLayouter->DistributeRows( maRect, nFirstRow, nLastRow, bOptimize, bMinimize );
2420  }
2421 }
2422 
2423 
2425 {
2426  if( mpImpl.is() )
2427  {
2428  mpImpl->LayoutTable( maRect, false, false );
2429  }
2430 
2432 }
2433 
2434 
2436 {
2437  if( mpImpl.is() && mpImpl->mxTable.is() )
2438  mpImpl->mxTable->lockBroadcasts();
2439 }
2440 
2441 
2443 {
2444  if( mpImpl.is() && mpImpl->mxTable.is() )
2445  mpImpl->mxTable->unlockBroadcasts();
2446 }
2447 
2449 {
2450  xmlTextWriterStartElement(pWriter, BAD_CAST("SdrTableObj"));
2451  xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
2452 
2453  SdrObject::dumpAsXml(pWriter);
2454 
2455  mpImpl->dumpAsXml(pWriter);
2456 
2457  xmlTextWriterEndElement(pWriter);
2458 }
2459 
2460 bool SdrTableObj::createTableEdgesJson(boost::property_tree::ptree & rJsonRoot)
2461 {
2462  if (!mpImpl.is() || !mpImpl->mxTable.is())
2463  return false;
2464 
2466  boost::property_tree::ptree aTableColumns;
2467  {
2468  aTableColumns.put("tableOffset", convertMm100ToTwip(aRect.Left()));
2469 
2470  boost::property_tree::ptree aEntries;
2471  auto const & aEdges = mpImpl->mpLayouter->getVerticalEdges();
2472  for (auto & rEdge : aEdges)
2473  {
2474  if (rEdge.nIndex == 0)
2475  {
2476  aTableColumns.put("left", convertMm100ToTwip(rEdge.nPosition));
2477  }
2478  else if (rEdge.nIndex == sal_Int32(aEdges.size() - 1))
2479  {
2480  aTableColumns.put("right", convertMm100ToTwip(rEdge.nPosition));
2481  }
2482  else
2483  {
2484  boost::property_tree::ptree aEntry;
2485  aEntry.put("position", convertMm100ToTwip(rEdge.nPosition));
2486  aEntry.put("min", convertMm100ToTwip(rEdge.nPosition + rEdge.nMin));
2487  aEntry.put("max", convertMm100ToTwip(rEdge.nPosition + rEdge.nMax));
2488  aEntry.put("hidden", false);
2489  aEntries.push_back(std::make_pair("", aEntry));
2490  }
2491  }
2492  aTableColumns.push_back(std::make_pair("entries", aEntries));
2493  }
2494  rJsonRoot.add_child("columns", aTableColumns);
2495 
2496  boost::property_tree::ptree aTableRows;
2497  {
2498  aTableRows.put("tableOffset", convertMm100ToTwip(aRect.Top()));
2499 
2500  boost::property_tree::ptree aEntries;
2501  auto const & aEdges = mpImpl->mpLayouter->getHorizontalEdges();
2502  for (auto & rEdge : aEdges)
2503  {
2504  if (rEdge.nIndex == 0)
2505  {
2506  aTableRows.put("left", convertMm100ToTwip(rEdge.nPosition));
2507  }
2508  else if (rEdge.nIndex == sal_Int32(aEdges.size() - 1))
2509  {
2510  aTableRows.put("right", convertMm100ToTwip(rEdge.nPosition));
2511  }
2512  else
2513  {
2514  boost::property_tree::ptree aEntry;
2515  aEntry.put("position", convertMm100ToTwip(rEdge.nPosition));
2516  aEntry.put("min", convertMm100ToTwip(rEdge.nPosition + rEdge.nMin));
2517  aEntry.put("max", convertMm100ToTwip(rEdge.nPosition + rEdge.nMax));
2518  aEntry.put("hidden", false);
2519  aEntries.push_back(std::make_pair("", aEntry));
2520  }
2521  }
2522  aTableRows.push_back(std::make_pair("entries", aEntries));
2523  }
2524  rJsonRoot.add_child("rows", aTableRows);
2525  return true;
2526 }
2527 
2528 }
2529 
2530 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool findMergeOrigin(const TableModelRef &xTable, sal_Int32 nMergedX, sal_Int32 nMergedY, sal_Int32 &rOriginX, sal_Int32 &rOriginY)
returns true if the cell(nMergedX,nMergedY) is merged with other cells.
Point TopLeft() const
long getHeight() const
const int nColCount
void LayoutTable(tools::Rectangle &rArea, bool bFitWidth, bool bFitHeight)
Definition: svdotable.cxx:787
virtual sal_uInt16 GetObjIdentifier() const override
Definition: svdotable.cxx:1449
CellPos getNextRow(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:1088
long GetWidth() const
virtual std::unique_ptr< sdr::properties::BaseProperties > CreateObjectSpecificProperties() override
Definition: svdotable.cxx:842
CellPos getRightCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:950
virtual OutlinerParaObject * GetOutlinerParaObject() const override
Definition: svdotable.cxx:1894
void setHeight(long n)
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdotable.cxx:2381
static sal_Int32 lastRowCount
Definition: svdotable.cxx:246
long GetHeight() const
css::uno::Reference< css::table::XTable > getTable() const
Definition: svdotable.cxx:905
virtual bool NbcAdjustTextFrameWidthAndHeight(bool bHgt=true, bool bWdt=true)
Definition: svdotxat.cxx:239
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:854
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdotable.cxx:851
constexpr sal_uInt16 SDRATTR_TABLE_FIRST(SDRATTR_CUSTOMSHAPE_LAST+1)
void setTableStyle(const css::uno::Reference< css::container::XIndexAccess > &xAutoFormatStyle)
Definition: svdotable.cxx:1275
struct _xmlTextWriter * xmlTextWriterPtr
sal_Int32 getRowCount() const
Definition: svdotable.cxx:782
CellPos getUpCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:965
long AdjustWidth(long n)
SdrObjUserCall * pUserCall
Definition: svdobj.hxx:924
media shape
Definition: svdobj.hxx:148
long Height() const
virtual bool IsAutoGrowWidth() const override
Definition: svdotable.cxx:1394
const Point & GetStart() const
Definition: svddrag.hxx:92
Point BottomLeft() const
virtual SdrObjGeoData * NewGeoData() const override
A derived class must override these 3 methods if it has own geometric data that must be saved for Und...
Definition: svdotable.cxx:2366
GeoStat aGeo
Definition: svdotext.hxx:185
CellRef getCell(const CellPos &rPos) const
Definition: svdotable.cxx:752
SdrHdlKind
Definition: svdhdl.hxx:52
long getWidth() const
void SetPaperSize(const Size &rSize)
virtual bool beginSpecialDrag(SdrDragStat &rDrag) const override
Definition: svdotable.cxx:2180
bool isValid(const sdr::table::CellPos &rPos) const
Definition: svdotable.cxx:911
virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat &rDrag) const override
Polygon dragged by the user when creating the object.
Definition: svdotable.cxx:2341
basegfx::B2DPolyPolygon getSpecialDragPoly(const SdrDragStat &rDrag) const
void CropTableModelToSelection(const CellPos &rStart, const CellPos &rEnd)
Definition: svdotable.cxx:275
SdrOutliner * pEdtOutl
Definition: svdotext.hxx:196
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdotable.cxx:1957
void TakeTextRect(const sdr::table::CellPos &rPos, SdrOutliner &rOutliner,::tools::Rectangle &rTextRect, bool bNoEditText,::tools::Rectangle *pAnchorRect) const
At the same time, we set the text in the outliner (if applicable the EditOutliners') as well as the P...
void createCell(sdr::table::CellRef &xCell)
Definition: svdotable.cxx:2360
virtual void setActiveText(sal_Int32 nIndex) override
Changes the current active text.
Definition: svdotable.cxx:1347
virtual bool IsFontwork() const override
Definition: svdotable.cxx:2070
bool bDisableAutoWidthOnDragging
Definition: svdotext.hxx:245
Abstract base class (ABC) for all UndoActions of DrawingEngine.
Definition: svdundo.hxx:54
bool IsInserted() const
Definition: svdobj.hxx:793
virtual void TakeTextEditArea(Size *pPaperMin, Size *pPaperMax, tools::Rectangle *pViewInit, tools::Rectangle *pViewMin) const override
Definition: svdotable.cxx:1641
sal_uInt32 GetPointNum() const
Definition: svdhdl.hxx:222
virtual sal_uInt32 GetHdlCount() const override
Via GetHdlCount the number of Handles can be retrieved.
Definition: svdotxdr.cxx:36
virtual void SetBoundRectDirty()
Definition: svdobj.cxx:310
SdrOutliner * GetCellTextEditOutliner(const sdr::table::Cell &rCell) const
Definition: svdotable.cxx:1375
void CropTableModelToSelection(const CellPos &rStart, const CellPos &rEnd)
Definition: svdotable.cxx:2394
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: svdotable.cxx:1426
const sal_Int32 first_column_style
Definition: tabledesign.hxx:31
constexpr sal_uInt16 EE_ITEMS_END(EE_FEATURE_END)
sal_Int32 GetParagraphCount() const
virtual SfxItemSet & GetItemSet()
virtual void BrkCreate(SdrDragStat &rStat) override
Definition: svdotable.cxx:2330
rtl::Reference< SdrTableObjImpl > mpImpl
Definition: svdotable.hxx:281
virtual void EndTextEdit(SdrOutliner &rOutl) override
Definition: svdotable.cxx:1854
constexpr sal_uInt16 SDRATTR_MISC_LAST(SDRATTR_TEXT_CHAINNEXTNAME)
const sal_Int32 last_column_style
Definition: tabledesign.hxx:32
EEControlBits
All geometrical data of an arbitrary object for use in undo/redo.
Definition: svdobj.hxx:226
CellPos getLeftCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:935
virtual void NbcMove(const Size &rSiz) override
The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and SetLogicRect call the corresponding ...
Definition: svdotable.cxx:1948
constexpr TypedWhichId< SvxFrameDirectionItem > EE_PARA_WRITINGDIR(EE_PARA_START+0)
virtual void SetChanged() override
Definition: svdotable.cxx:2424
constexpr sal_uInt16 SDRATTR_START(XATTR_START)
long AdjustBottom(long nVertMoveDelta)
virtual sal_uInt32 GetHdlCount() const override
Via GetHdlCount the number of Handles can be retrieved.
Definition: svdotable.cxx:2075
bool mbInEditMode
Definition: svdotext.hxx:235
void Move(long nHorzMoveDelta, long nVertMoveDelta)
bool bSnapRectDirty
Definition: svdobj.hxx:929
Point RightCenter() const
virtual PointerStyle GetCreatePointer() const override
get the cursor/pointer that signals creating this object
Definition: svdotable.cxx:2354
bool IsEmpty() const
TableStyleSettings maTableStyle
Definition: svdotable.cxx:199
editeng::SvxBorderLine * getBorderLine(sal_Int32 nEdgeX, sal_Int32 nEdgeY, bool bHorizontal) const
returns the requested borderline in rpBorderLine or a null pointer if there is no border at this edge...
Provides information about various ZObject properties.
Definition: svdobj.hxx:248
const SdrHdl * GetHdl() const
Definition: svddrag.hxx:101
virtual bool applySpecialDrag(SdrDragStat &rDrag) override
Definition: svdotable.cxx:2216
virtual SdrText * getText(sal_Int32 nIndex) const override
Returns the nth available text.
Definition: svdotable.cxx:1312
virtual const tools::Rectangle & GetLogicRect() const override
Definition: svdotable.cxx:1802
void SetControlWord(EEControlBits nWord)
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
long GetDX() const
Definition: svddrag.hxx:148
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
virtual const tools::Rectangle & GetSnapRect() const override
Definition: svdotable.cxx:1790
void DragEdge(bool mbHorizontal, int nEdge, sal_Int32 nOffset)
Definition: svdotable.cxx:585
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdotext.cxx:1432
void SetTextSizeDirty()
Definition: svdotext.hxx:288
rtl::Reference< Cell > CellRef
Definition: celltypes.hxx:33
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: svdmodel.cxx:546
static bool IsFuzzing()
Point BottomCenter() const
int nCount
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
Definition: svdotable.cxx:1796
css::text::WritingMode GetValue() const
virtual bool IsReallyEdited() const override
Returns true only if we are in edit mode and the user actually changed anything.
Definition: svdotable.cxx:2065
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2140
tools::Rectangle maRect
Definition: svdotext.hxx:182
void SetOrtho4Possible(bool bOn=true)
Definition: svddrag.hxx:126
bool bNoShear
Definition: svdotext.hxx:232
SdrTableObjImpl & operator=(const SdrTableObjImpl &rSource)
Definition: svdotable.cxx:378
void TakeCreateRect(tools::Rectangle &rRect) const
Definition: svddrag.cxx:115
void DistributeColumns(sal_Int32 nFirstColumn, sal_Int32 nLastColumn, const bool bOptimize, const bool bMinimize)
Definition: svdotable.cxx:2404
const sdr::table::TableStyleSettings & getTableStyleSettings() const
Definition: svdotable.cxx:1131
bool bClosedObj
Definition: svdobj.hxx:942
long Top() const
CellPos getPreviousCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:993
EEControlBits GetControlWord() const
void SetObjectItem(const SfxPoolItem &rItem)
Definition: svdobj.cxx:1894
Point LeftCenter() const
void DistributeRows(sal_Int32 nFirstRow, sal_Int32 nLastRow, const bool bOptimize, const bool bMinimize)
Definition: svdotable.cxx:2414
void getActiveCellPos(sdr::table::CellPos &rPos) const
Definition: svdotable.cxx:1601
virtual EEAnchorMode GetOutlinerViewAnchorMode() const override
Definition: svdotable.cxx:1701
static SdrTableObjImpl * lastLayoutTable
Definition: svdotable.cxx:240
virtual bool HasText() const override
Definition: svdotable.cxx:1399
tools::Rectangle ImpDragCalcRect(const SdrDragStat &rDrag) const
Definition: svdotxdr.cxx:72
void SetEndDragChangesLayout(bool bOn)
Definition: svddrag.hxx:137
SdrOutliner & GetHitTestOutliner() const
Definition: svdmodel.hxx:319
CellPos getPreviousRow(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:1062
virtual ~SdrTableObjImpl() override
Definition: svdotable.cxx:268
Point BottomRight() const
const SfxPoolItem & GetObjectItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:1919
virtual void AddToHdlList(SdrHdlList &rHdlList) const override
Definition: svdotable.cxx:2087
constexpr TypedWhichId< SvxWritingModeItem > SDRATTR_TEXTDIRECTION(SDRATTR_NOTPERSIST_FIRST+34)
void SetNoSnap(bool bOn=true)
Definition: svddrag.hxx:121
std::vector< sal_Int32 > getColumnWidths() const
Get widths of the columns in the table.
Definition: svdotable.cxx:772
void ResizeRect(tools::Rectangle &rRect, const Point &rRef, const Fraction &rxFact, const Fraction &ryFact)
Definition: svdtrans.cxx:37
Reference< XIndexAccess > mxTableStyle
Definition: svdotable.cxx:200
SdrTableObj & operator=(const SdrTableObj &rObj)
Definition: svdotable.cxx:1756
void SetObj(SdrObject *pNewObj)
Definition: svdhdl.cxx:377
void init(sal_Int32 nColumns, sal_Int32 nRows)
Definition: svdotable.cxx:880
long GetTextLeftDistance() const
Left inner spacing to borders.
Definition: svdotext.cxx:1742
void SetText(const OutlinerParaObject &)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
#define DBG_ASSERT(sCon, aError)
virtual void SAL_CALL modified(const css::lang::EventObject &aEvent) override
Definition: svdotable.cxx:663
int i
Reference< XAnimationNode > Clone(const Reference< XAnimationNode > &xSourceNode, const SdPage *pSource, const SdPage *pTarget)
const sal_Int32 first_row_style
Definition: tabledesign.hxx:29
virtual void NbcSetLogicRect(const tools::Rectangle &rRect) override
Definition: svdotable.cxx:1924
void MoveTo(SdrHdlList &rOther)
Definition: svdhdl.cxx:2328
class SAL_NO_VTABLE XPropertySet
Definition: xmlexchg.hxx:28
bool bTextSizeDirty
Definition: svdotext.hxx:233
TableHitKind
SdrTableHitKind.
Definition: svdotable.hxx:51
OUString sName
virtual bool isInUse() override
Definition: svdotable.cxx:725
const sal_Int32 even_columns_style
Definition: tabledesign.hxx:35
void BroadcastObjectChange() const
Definition: svdobj.cxx:905
sal_Int32 getColumnWidth(sal_Int32 nColumn) const
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
CellPos getLastCell() const
Definition: svdotable.cxx:923
sal_Int32 GetPointCount() const
Definition: svddrag.hxx:91
SdrTextObj & operator=(const SdrTextObj &rObj)
Definition: svdotext.cxx:1007
void ActionChanged() const
Definition: svdobj.cxx:257
constexpr sal_uInt16 EE_ITEMS_START(OWN_ATTR_VALUE_END+1)
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
Definition: svdotable.cxx:743
void changeEdge(bool bHorizontal, int nEdge, sal_Int32 nOffset)
Definition: svdotable.cxx:1571
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:273
bool IsModified() const
void TakeTextAnchorRect(const sdr::table::CellPos &rPos,::tools::Rectangle &rAnchorRect) const
virtual void SetLogicRect(const tools::Rectangle &rRect)
Definition: svdobj.cxx:1631
virtual bool EndCreate(SdrDragStat &rStat, SdrCreateCmd eCmd) override
Definition: svdotable.cxx:2323
virtual void NbcMove(const Size &rSiz) override
The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and SetLogicRect call the corresponding ...
Definition: svdotxtr.cxx:94
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdotable.cxx:2372
void SetEndDragChangesAttributes(bool bOn)
Definition: svddrag.hxx:133
void SetMoveOutside(bool bMoveOutside)
Definition: svdhdl.cxx:319
static std::vector< sal_Int32 > lastColWidths
Definition: svdotable.cxx:248
Abstract DrawObject.
Definition: svdobj.hxx:312
SdrObjKind eTextKind
Definition: svdotext.hxx:204
void ClearModifyFlag()
TableHitKind CheckTableHit(const Point &rPos, sal_Int32 &rnX, sal_Int32 &rnY, const sal_uInt16 aTol=0) const
Definition: svdotable.cxx:1155
std::unique_ptr< TableLayouter > mpLayouter
Definition: svdotable.cxx:197
OUString GetName() const
Definition: svdobj.cxx:698
tools::Rectangle maLogicRect
Definition: svdotable.hxx:280
Size GetSize() const
CellPos getDownCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:979
virtual SdrTableObj * CloneSdrObject(SdrModel &rTargetModel) const override
Definition: svdotable.cxx:1751
bool operator==(const TableStyleSettings &r) const
Definition: svdotable.cxx:179
bool bTextFrame
Definition: svdotext.hxx:231
css::text::WritingMode GetWritingMode() const
Definition: svdotable.cxx:2030
Paragraph * GetParagraph(sal_Int32 nAbsPos) const
void setTableStyleSettings(const sdr::table::TableStyleSettings &rStyle)
Definition: svdotable.cxx:1145
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
virtual SdrText * getActiveText() const override
Returns the currently active text.
Definition: svdotable.cxx:1305
const css::uno::Reference< css::container::XIndexAccess > & getTableStyle() const
Definition: svdotable.cxx:1287
long GetDY() const
Definition: svddrag.hxx:149
const SfxItemSet & GetActiveCellItemSet() const
Definition: svdotable.cxx:1270
static SfxUnoStyleSheet * getUnoStyleSheet(const css::uno::Reference< css::style::XStyle > &xStyle)
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
bool isEdgeVisible(sal_Int32 nEdgeX, sal_Int32 nEdgeY, bool bHorizontal) const
checks if the given edge is visible.
virtual const tools::Rectangle & GetLastBoundRect() const
Definition: svdobj.cxx:868
virtual void NbcSetOutlinerParaObject(std::unique_ptr< OutlinerParaObject > pTextObject) override
Definition: svdotable.cxx:1904
static CellPos getFirstCell()
Definition: svdotable.cxx:917
size_t GetHdlCount() const
Definition: svdhdl.hxx:461
SdrHdl * GetHdl(size_t nNum) const
Definition: svdhdl.hxx:462
constexpr sal_uInt16 SDRATTR_SHADOW_LAST(SDRATTR_SHADOWBLUR)
void AddUndo(SdrUndoAction *pUndo)
Add an undo action that should be on the undo stack after ending text edit.
Definition: svdotable.cxx:2055
void SetActionRect(const tools::Rectangle &rR)
Definition: svddrag.hxx:157
std::unique_ptr< OutlinerParaObject > CreateParaObject(sal_Int32 nStartPara=0, sal_Int32 nParaCount=EE_PARA_ALL) const
constexpr sal_uInt16 SDRATTR_TABLE_LAST(SDRATTR_TABLE_TEXT_ROTATION)
sal_Int32 getRowCount() const
Definition: svdotable.cxx:1566
friend class SdrTableObjImpl
Definition: svdotable.hxx:97
bool IsTextEditActive() const
Definition: svdotable.hxx:179
EditStatusFlags GetStatusWord() const
void SetMaxAutoPaperSize(const Size &rSz)
virtual bool BegTextEdit(SdrOutliner &rOutl) override
Definition: svdotable.cxx:1813
void init(SdrTableObj *pTable, sal_Int32 nColumns, sal_Int32 nRows)
Definition: svdotable.cxx:365
virtual bool MovCreate(SdrDragStat &rStat) override
Definition: svdotable.cxx:2310
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdotext.cxx:1440
static tools::Rectangle lastLayoutInputRectangle
Definition: svdotable.cxx:241
virtual bool BegCreate(SdrDragStat &rStat) override
Every object must be able to create itself interactively.
Definition: svdotable.cxx:2299
const sal_Int32 odd_columns_style
Definition: tabledesign.hxx:36
static tools::Rectangle lastLayoutResultRectangle
Definition: svdotable.cxx:242
tools::Rectangle maLogicRect
Definition: svdotable.cxx:148
sal_Int32 GetValidDragOffset(const SdrDragStat &rDrag) const
virtual OUString TakeObjNameSingul() const override
Definition: svdotable.cxx:1728
const sal_Int32 body_style
Definition: tabledesign.hxx:37
virtual OutlinerParaObject * GetOutlinerParaObject() const override
Definition: svdotext.cxx:1354
const sal_Int32 even_rows_style
Definition: tabledesign.hxx:33
virtual void AdjustToMaxRect(const tools::Rectangle &rMaxRect, bool bShrinkOnly=false) override
Definition: svdotable.cxx:1940
virtual void onEditOutlinerStatusEvent(EditStatus *pEditStatus) override
called from the SdrObjEditView during text edit when the status of the edit outliner changes ...
Definition: svdotable.cxx:1410
OUString aName
virtual bool IsVerticalWriting() const override
Definition: svdotable.cxx:2013
CellPos getNextCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:1020
void SetMinAutoPaperSize(const Size &rSz)
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: svdobj.cxx:1706
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: svdotable.cxx:730
void SetBottom(long v)
virtual void NbcReformatText() override
Definition: svdotable.cxx:2007
void Init(OutlinerMode nOutlinerMode)
void SetOutlinerParaObject(std::unique_ptr< OutlinerParaObject > pTextObject)
Definition: svdobj.cxx:1733
virtual void RecalcSnapRect() override
Snap is not done on the BoundRect but if possible on logic coordinates (i.e.
Definition: svdotable.cxx:1808
void SetRefDevice(OutputDevice *pRefDev)
long AdjustTop(long nVertMoveDelta)
virtual bool hasSpecialDrag() const override
The standard transformations (Move,Resize,Rotate,Mirror,Shear) are taken over by the View (TakeXorPol...
Definition: svdotable.cxx:2175
Size aTextSize
Definition: svdotext.hxx:191
bool IsHorizontalEdge() const
const Point & GetNow() const
Definition: svddrag.hxx:95
sal_Int32 getRowHeight(sal_Int32 nRow) const
void SetUpdateMode(bool bUpdate)
long Left() const
sal_Int32 getColumnCount() const
Definition: svdotable.cxx:1561
static sal_Int32 lastColCount
Definition: svdotable.cxx:247
void setActiveCell(const sdr::table::CellPos &rPos)
Definition: svdotable.cxx:1577
PointerStyle
sal_Int32 getColumnCount() const
Definition: svdotable.cxx:767
constexpr sal_Int64 convertMm100ToTwip(sal_Int64 n)
virtual void SetRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:435
TableStyleSettings.
Definition: svdotable.hxx:75
static WritingMode lastLayoutMode
Definition: svdotable.cxx:245
EEAnchorMode
void UpdateCells(tools::Rectangle const &rArea)
Definition: svdotable.cxx:828
virtual sal_Int32 getTextCount() const override
Returns the number of texts available for this object.
Definition: svdotable.cxx:1330
ScXMLEditAttributeMap::Entry const aEntries[]
void SetTextObj(const SdrTextObj *pObj)
Definition: svdoutl.cxx:40
SdrTableObj(SdrModel &rSdrModel)
Definition: svdotable.cxx:856
virtual bool BckCreate(SdrDragStat &rStat) override
Definition: svdotable.cxx:2335
virtual bool IsAutoGrowHeight() const override
Definition: svdotable.cxx:1389
bool UpdateFields()
std::vector< std::unique_ptr< SdrUndoAction > > maUndos
Definition: svdotable.cxx:201
const SdrTextObj * GetTextObj() const
Definition: svdoutl.cxx:86
void Clear()
virtual sal_Int32 CheckTextHit(const Point &rPnt) const override
Returns the index of the text that contains the given point or -1.
Definition: svdotable.cxx:1363
SdrCreateCmd
Definition: svdtypes.hxx:27
virtual void SetVerticalWriting(bool bVertical) override
Definition: svdotable.cxx:2020
virtual void SetChanged()
Definition: svdobj.cxx:929
virtual ~SdrTableObj() override
Definition: svdotable.cxx:896
constexpr sal_uInt16 SDRATTR_MISC_FIRST(SDRATTR_CAPTION_LAST+1)
void SetSkipChangeLayout(bool bSkipChangeLayout)
Next time layouting would be done, skip it (to layout at the end of multiple actions).
Definition: svdotable.cxx:2060
TableStyleSettings & operator=(const TableStyleSettings &rStyle)
Definition: svdotable.cxx:168
void setWidth(long nWidth)
virtual OUString TakeObjNamePlural() const override
Definition: svdotable.cxx:1745
static void ImpJustifyRect(tools::Rectangle &rRect)
Definition: svdotext.cxx:374
virtual basegfx::B2DPolyPolygon getSpecialDragPoly(const SdrDragStat &rDrag) const override
Definition: svdotable.cxx:2277
Point TopRight() const
SdrTextVertAdjust
Definition: sdtaitm.hxx:29
void SendUserCall(SdrUserCallType eUserCall, const tools::Rectangle &rBoundRect) const
Definition: svdobj.cxx:2654
virtual bool AdjustTextFrameWidthAndHeight() override
Definition: svdotable.cxx:1968
const sdr::table::CellRef & getActiveCell() const
The active table has the focus or is currently edited.
Definition: svdotable.cxx:1542
const TableLayouter & getTableLayouter() const
Definition: svdotable.cxx:1383
bool GetUpdateMode() const
const sal_Int32 last_row_style
Definition: tabledesign.hxx:30
void AddHdl(std::unique_ptr< SdrHdl > pHdl)
Definition: svdhdl.cxx:2294
Point TopCenter() const
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override
Definition: svdotable.cxx:2448
SdrHdlKind GetKind() const
Definition: svdhdl.hxx:194
void getCellBounds(const sdr::table::CellPos &rPos,::tools::Rectangle &rCellRect)
Definition: svdotable.cxx:1607
bool createTableEdgesJson(boost::property_tree::ptree &rJsonRoot)
Definition: svdotable.cxx:2460
const sal_Int32 odd_rows_style
Definition: tabledesign.hxx:34
void setHeight(long nHeight)
const Size & GetPaperSize() const