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