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 #include <tools/diagnose_ex.h>
57 #include <tools/UnitConversion.hxx>
58 
59 #include <boost/property_tree/ptree.hpp>
60 
61 using ::com::sun::star::uno::Any;
62 using ::com::sun::star::uno::Reference;
63 using ::com::sun::star::uno::UNO_QUERY;
64 using ::com::sun::star::uno::UNO_QUERY_THROW;
65 using ::com::sun::star::uno::Exception;
66 using ::com::sun::star::container::XIndexAccess;
67 using ::com::sun::star::style::XStyle;
68 using ::com::sun::star::table::XTableRows;
69 using ::com::sun::star::table::XTableColumns;
70 using ::com::sun::star::table::XTable;
72 using ::com::sun::star::util::XModifyBroadcaster;
75 using namespace ::com::sun::star;
76 using namespace ::com::sun::star::text;
77 using namespace ::com::sun::star::container;
78 using namespace ::com::sun::star::style;
79 
80 namespace sdr::table {
81 
82 namespace {
83 
84 class TableProperties : public TextProperties
85 {
86 protected:
87  // create a new itemset
88  std::unique_ptr<SfxItemSet> CreateObjectSpecificItemSet(SfxItemPool& rPool) override;
89 
90 public:
91  // basic constructor
92  explicit TableProperties(SdrObject& rObj );
93 
94  // constructor for copying, but using new object
95  TableProperties(const TableProperties& rProps, SdrObject& rObj );
96 
97  // Clone() operator, normally just calls the local copy constructor
98  std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
99 
100  virtual void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem = nullptr) override;
101 };
102 
103 }
104 
105 TableProperties::TableProperties(SdrObject& rObj)
106 : TextProperties(rObj)
107 {
108 }
109 
110 TableProperties::TableProperties(const TableProperties& rProps, SdrObject& rObj)
111 : TextProperties(rProps, rObj)
112 {
113 }
114 
115 std::unique_ptr<BaseProperties> TableProperties::Clone(SdrObject& rObj) const
116 {
117  return std::unique_ptr<BaseProperties>(new TableProperties(*this, rObj));
118 }
119 
120 void TableProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
121 {
122  if( nWhich == SDRATTR_TEXTDIRECTION )
123  AttributeProperties::ItemChange( nWhich, pNewItem );
124  else
125  TextProperties::ItemChange( nWhich, pNewItem );
126 }
127 
128 // create a new itemset
129 std::unique_ptr<SfxItemSet> TableProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
130 {
131  return std::make_unique<SfxItemSet>(rPool,
132 
133  // range from SdrAttrObj
137 
138  // range for SdrTableObj
140 
141  // range from SdrTextObj
143 }
144 
145 namespace {
146 
147 class TableObjectGeoData : public SdrTextObjGeoData
148 {
149 public:
151 };
152 
153 }
154 
155 TableStyleSettings::TableStyleSettings()
156 : mbUseFirstRow(true)
157 , mbUseLastRow(false)
158 , mbUseFirstColumn(false)
159 , mbUseLastColumn(false)
160 , mbUseRowBanding(true)
161 , mbUseColumnBanding(false)
162 {
163 }
164 
166 {
167  (*this) = rStyle;
168 }
169 
171 {
172  mbUseFirstRow = rStyle.mbUseFirstRow;
173  mbUseLastRow = rStyle.mbUseLastRow;
178  return *this;
179 }
180 
182 {
183  return
184  (mbUseFirstRow == rStyle.mbUseFirstRow) &&
185  (mbUseLastRow == rStyle.mbUseLastRow) &&
186  (mbUseFirstColumn == rStyle.mbUseFirstColumn) &&
187  (mbUseLastColumn == rStyle.mbUseLastColumn) &&
188  (mbUseRowBanding == rStyle.mbUseRowBanding) &&
190 }
191 
192 
193 class SdrTableObjImpl : public TableDesignUser, public ::cppu::WeakImplHelper< css::util::XModifyListener >
194 {
195 public:
199  std::unique_ptr<TableLayouter> mpLayouter;
202  Reference< XIndexAccess > mxTableStyle;
203  std::vector<std::unique_ptr<SdrUndoAction>> maUndos;
205 
206  void CropTableModelToSelection(const CellPos& rStart, const CellPos& rEnd);
207 
208  CellRef getCell( const CellPos& rPos ) const;
209  void LayoutTable( tools::Rectangle& rArea, bool bFitWidth, bool bFitHeight );
210 
211  void ApplyCellStyles();
212  void UpdateCells( tools::Rectangle const & rArea );
213 
214  SdrTableObjImpl();
215  virtual ~SdrTableObjImpl() override;
216 
217  void init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows );
218  void dispose();
219 
220  sal_Int32 getColumnCount() const;
222  std::vector<sal_Int32> getColumnWidths() const;
223  sal_Int32 getRowCount() const;
224 
225  void DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset );
226 
227  SdrTableObjImpl& operator=( const SdrTableObjImpl& rSource );
228 
229  // XModifyListener
230  virtual void SAL_CALL modified( const css::lang::EventObject& aEvent ) override;
231 
232  // XEventListener
233  virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
234 
235  void update();
236 
237  void connectTableStyle();
238  void disconnectTableStyle();
239  virtual bool isInUse() override;
240  void dumpAsXml(xmlTextWriterPtr pWriter) const;
241 private:
245  static bool lastLayoutFitWidth;
246  static bool lastLayoutFitHeight;
248  static sal_Int32 lastRowCount;
249  static sal_Int32 lastColCount;
250  static std::vector<sal_Int32> lastColWidths;
251 };
252 
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  const OUString sHeight( "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  const OUString sWidth( "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  const OUString sSize( "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  }
608  }
609  else
610  {
611  /*
612  fixes fdo#59889 and resizing of table in edge dragging
613  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
614  In LTR table vertical edge responsible for dragging of column x(x=0 to N-1) is, Edge x+1
615  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
616  In LTR table dragging of edge 0(for RTL table edge N) does nothing.
617  */
618  //Todo: Implement Dragging functionality for leftmost edge of table.
619  if (nEdge <= getColumnCount())
620  {
621  const bool bRTL = mpTableObj != nullptr && (mpTableObj->GetWritingMode() == WritingMode_RL_TB);
622  sal_Int32 nWidth;
623  if(bRTL)
624  {
625  nWidth = mpLayouter->getColumnWidth( nEdge );
626  }
627  else
628  {
629  nWidth = mpLayouter->getColumnWidth( (!nEdge)?nEdge:(nEdge-1) );
630  }
631  Reference< XIndexAccess > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
632  nWidth += nOffset;
633  if(bRTL && nEdge<getColumnCount())
634  {
635  Reference< XPropertySet > xColSet( xCols->getByIndex( nEdge ), UNO_QUERY_THROW );
636  xColSet->setPropertyValue( sSize, Any( nWidth ) );
637  }
638  else if(!bRTL && nEdge>0)
639  {
640  Reference< XPropertySet > xColSet( xCols->getByIndex( nEdge-1 ), UNO_QUERY_THROW );
641  xColSet->setPropertyValue( sSize, Any( nWidth ) );
642  }
643  /* To prevent the table resizing on edge dragging */
644  if( nEdge > 0 && nEdge < mxTable->getColumnCount() )
645  {
646  if( bRTL )
647  nEdge--;
648 
649  nWidth = mpLayouter->getColumnWidth(nEdge);
650  nWidth = std::max(static_cast<sal_Int32>(nWidth - nOffset), sal_Int32(0));
651 
652  Reference<XPropertySet> xColSet(xCols->getByIndex(nEdge), UNO_QUERY_THROW);
653  xColSet->setPropertyValue(sSize, Any(nWidth));
654  }
655  }
656  }
657  }
658  catch( Exception& )
659  {
660  TOOLS_WARN_EXCEPTION("svx.table", "");
661  }
662 }
663 
664 
665 // XModifyListener
666 
667 
668 void SAL_CALL SdrTableObjImpl::modified( const css::lang::EventObject& /*aEvent*/ )
669 {
670  update();
671 }
672 
674 {
675  // source can be the table model itself or the assigned table template
676  TableModelNotifyGuard aGuard( mxTable.get() );
677  if( !mpTableObj )
678  return;
679 
681  {
682  if(maEditPos.mnRow >= getRowCount())
684 
687 
689  }
690 
691  ApplyCellStyles();
692 
694  LayoutTable( mpTableObj->maRect, false, false );
695 
699 }
700 
701 
703 {
704  if( mxTableStyle.is() )
705  {
706  Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY );
707  if( xBroadcaster.is() )
708  {
709  Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
710  xBroadcaster->addModifyListener( xListener );
711  }
712  }
713 }
714 
715 
717 {
718  if( mxTableStyle.is() )
719  {
720  Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY );
721  if( xBroadcaster.is() )
722  {
723  Reference< XModifyListener > xListener( static_cast< css::util::XModifyListener* >(this) );
724  xBroadcaster->removeModifyListener( xListener );
725  }
726  }
727 }
728 
729 
731 {
732  return mpTableObj && mpTableObj->IsInserted();
733 }
734 
736 {
737  xmlTextWriterStartElement(pWriter, BAD_CAST("SdrTableObjImpl"));
738  if (mpLayouter)
739  mpLayouter->dumpAsXml(pWriter);
740  mxTable->dumpAsXml(pWriter);
741  xmlTextWriterEndElement(pWriter);
742 }
743 
744 
745 // XEventListener
746 
747 
748 void SAL_CALL SdrTableObjImpl::disposing( const css::lang::EventObject& /*Source*/ )
749 {
750  mxActiveCell.clear();
751  mxTable.clear();
752  mpLayouter.reset();
753  mpTableObj = nullptr;
754 }
755 
756 
758 {
759  CellRef xCell;
760  if( mxTable.is() ) try
761  {
762  xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
763  }
764  catch( Exception& )
765  {
766  TOOLS_WARN_EXCEPTION("svx.table", "");
767  }
768  return xCell;
769 }
770 
771 
773 {
774  return mxTable.is() ? mxTable->getColumnCount() : 0;
775 }
776 
777 std::vector<sal_Int32> SdrTableObjImpl::getColumnWidths() const
778 {
779  std::vector<sal_Int32> aRet;
780 
781  if (mxTable.is())
782  aRet = mxTable->getColumnWidths();
783 
784  return aRet;
785 }
786 
788 {
789  return mxTable.is() ? mxTable->getRowCount() : 0;
790 }
791 
792 void SdrTableObjImpl::LayoutTable( tools::Rectangle& rArea, bool bFitWidth, bool bFitHeight )
793 {
795  return;
796  if(!mpLayouter)
797  return;
798 
799  // Optimization: SdrTableObj::SetChanged() can call this very often, repeatedly
800  // with the same settings, noticeably increasing load time. Skip if already done.
801  bool bInteractiveMightGrowBecauseTextChanged =
803  WritingMode writingMode = mpTableObj->GetWritingMode();
804  if( bInteractiveMightGrowBecauseTextChanged
805  || lastLayoutTable != this || lastLayoutInputRectangle != rArea
806  || lastLayoutFitWidth != bFitWidth || lastLayoutFitHeight != bFitHeight
807  || lastLayoutMode != writingMode
808  || lastRowCount != getRowCount()
811  {
812  lastLayoutTable = this;
813  lastLayoutInputRectangle = rArea;
814  lastLayoutFitWidth = bFitWidth;
815  lastLayoutFitHeight = bFitHeight;
816  lastLayoutMode = writingMode;
819  // Column resize, when the total width and column count of the
820  // table is unchanged, but re-layout is still needed.
822  TableModelNotifyGuard aGuard( mxTable.get() );
823  mpLayouter->LayoutTable( rArea, bFitWidth, bFitHeight );
825  }
826  else
827  {
829  mpLayouter->UpdateBorderLayout();
830  }
831 }
832 
834 {
835  if( mpLayouter && mxTable.is() )
836  {
837  TableModelNotifyGuard aGuard( mxTable.get() );
838  mpLayouter->updateCells( rArea );
839  mxTable->setModified(true);
840  }
841 }
842 
843 
844 // BaseProperties section
845 
846 
847 std::unique_ptr<sdr::properties::BaseProperties> SdrTableObj::CreateObjectSpecificProperties()
848 {
849  return std::make_unique<TableProperties>(*this);
850 }
851 
852 
853 // DrawContact section
854 
855 
856 std::unique_ptr<sdr::contact::ViewContact> SdrTableObj::CreateObjectSpecificViewContact()
857 {
858  return std::make_unique<sdr::contact::ViewContactOfTableObj>(*this);
859 }
860 
862 : SdrTextObj(rSdrModel)
863 {
864  init( 1, 1 );
865 }
866 
868  SdrModel& rSdrModel,
869  const ::tools::Rectangle& rNewRect,
870  sal_Int32 nColumns,
871  sal_Int32 nRows)
872 : SdrTextObj(rSdrModel, rNewRect)
873  ,maLogicRect(rNewRect)
874 {
875  if( nColumns <= 0 )
876  nColumns = 1;
877 
878  if( nRows <= 0 )
879  nRows = 1;
880 
881  init( nColumns, nRows );
882 }
883 
884 
885 void SdrTableObj::init( sal_Int32 nColumns, sal_Int32 nRows )
886 {
887  bClosedObj = true;
888 
889  mpImpl = new SdrTableObjImpl;
890  mpImpl->init( this, nColumns, nRows );
891 
892  // Stuff done from old SetModel:
893  if( !maLogicRect.IsEmpty() )
894  {
896  mpImpl->LayoutTable( maRect, false, false );
897  }
898 }
899 
900 
902 {
903  mpImpl->dispose();
904 }
905 
906 
907 // table stuff
908 
909 
910 Reference< XTable > SdrTableObj::getTable() const
911 {
912  return Reference< XTable >( mpImpl->mxTable.get() );
913 }
914 
915 
916 bool SdrTableObj::isValid( const CellPos& rPos ) const
917 {
918  return (rPos.mnCol >= 0) && (rPos.mnCol < mpImpl->getColumnCount()) && (rPos.mnRow >= 0) && (rPos.mnRow < mpImpl->getRowCount());
919 }
920 
921 
923 {
924  return CellPos( 0,0 );
925 }
926 
927 
929 {
930  CellPos aPos;
931  if( mpImpl->mxTable.is() )
932  {
933  aPos.mnCol = mpImpl->getColumnCount()-1;
934  aPos.mnRow = mpImpl->getRowCount()-1;
935  }
936  return aPos;
937 }
938 
939 
940 CellPos SdrTableObj::getLeftCell( const CellPos& rPos, bool bEdgeTravel ) const
941 {
942  switch( GetWritingMode() )
943  {
944  default:
945  case WritingMode_LR_TB:
946  return getPreviousCell( rPos, bEdgeTravel );
947  case WritingMode_RL_TB:
948  return getNextCell( rPos, bEdgeTravel );
949  case WritingMode_TB_RL:
950  return getPreviousRow( rPos, bEdgeTravel );
951  }
952 }
953 
954 
955 CellPos SdrTableObj::getRightCell( const CellPos& rPos, bool bEdgeTravel ) const
956 {
957  switch( GetWritingMode() )
958  {
959  default:
960  case WritingMode_LR_TB:
961  return getNextCell( rPos, bEdgeTravel );
962  case WritingMode_RL_TB:
963  return getPreviousCell( rPos, bEdgeTravel );
964  case WritingMode_TB_RL:
965  return getNextRow( rPos, bEdgeTravel );
966  }
967 }
968 
969 
970 CellPos SdrTableObj::getUpCell( const CellPos& rPos, bool bEdgeTravel ) const
971 {
972  switch( GetWritingMode() )
973  {
974  default:
975  case WritingMode_LR_TB:
976  case WritingMode_RL_TB:
977  return getPreviousRow( rPos, bEdgeTravel );
978  case WritingMode_TB_RL:
979  return getPreviousCell( rPos, bEdgeTravel );
980  }
981 }
982 
983 
984 CellPos SdrTableObj::getDownCell( const CellPos& rPos, bool bEdgeTravel ) const
985 {
986  switch( GetWritingMode() )
987  {
988  default:
989  case WritingMode_LR_TB:
990  case WritingMode_RL_TB:
991  return getNextRow( rPos, bEdgeTravel );
992  case WritingMode_TB_RL:
993  return getNextCell( rPos, bEdgeTravel );
994  }
995 }
996 
997 
998 CellPos SdrTableObj::getPreviousCell( const CellPos& rPos, bool bEdgeTravel ) const
999 {
1000  CellPos aPos( rPos );
1001  if( mpImpl.is() )
1002  {
1003  CellRef xCell( mpImpl->getCell( aPos ) );
1004  if( xCell.is() && xCell->isMerged() )
1005  {
1006  sal_Int32 nTemp = 0;
1007  findMergeOrigin( mpImpl->mxTable.get(), aPos.mnCol, aPos.mnRow, aPos.mnCol, nTemp );
1008  }
1009 
1010  if( aPos.mnCol > 0 )
1011  {
1012  --aPos.mnCol;
1013  }
1014 
1015  else if( bEdgeTravel && (aPos.mnRow > 0) )
1016  {
1017  aPos.mnCol = mpImpl->mxTable->getColumnCount()-1;
1018  --aPos.mnRow;
1019  }
1020  }
1021  return aPos;
1022 }
1023 
1024 
1025 CellPos SdrTableObj::getNextCell( const CellPos& rPos, bool bEdgeTravel ) const
1026 {
1027  CellPos aPos( rPos );
1028  if( mpImpl.is() )
1029  {
1030  CellRef xCell( mpImpl->getCell( aPos ) );
1031  if( xCell.is() )
1032  {
1033  if( xCell->isMerged() )
1034  {
1035  findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow );
1036 
1037  xCell = mpImpl->getCell(aPos);
1038 
1039  if( xCell.is() )
1040  {
1041  aPos.mnCol += xCell->getColumnSpan();
1042  aPos.mnRow = rPos.mnRow;
1043  }
1044  }
1045  else
1046  {
1047  aPos.mnCol += xCell->getColumnSpan();
1048  }
1049 
1050  if( aPos.mnCol < mpImpl->mxTable->getColumnCount() )
1051  return aPos;
1052 
1053  if( bEdgeTravel && ((aPos.mnRow + 1) < mpImpl->getRowCount()) )
1054  {
1055  aPos.mnCol = 0;
1056  aPos.mnRow += 1;
1057  return aPos;
1058  }
1059  }
1060  }
1061 
1062  // last cell reached, no traveling possible
1063  return rPos;
1064 }
1065 
1066 
1067 CellPos SdrTableObj::getPreviousRow( const CellPos& rPos, bool bEdgeTravel ) const
1068 {
1069  CellPos aPos( rPos );
1070  if( mpImpl.is() )
1071  {
1072  CellRef xCell( mpImpl->getCell( aPos ) );
1073  if( xCell.is() && xCell->isMerged() )
1074  {
1075  sal_Int32 nTemp = 0;
1076  findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, nTemp, aPos.mnRow );
1077  }
1078 
1079  if( aPos.mnRow > 0 )
1080  {
1081  --aPos.mnRow;
1082  }
1083  else if( bEdgeTravel && (aPos.mnCol > 0) )
1084  {
1085  aPos.mnRow = mpImpl->mxTable->getRowCount()-1;
1086  --aPos.mnCol;
1087  }
1088  }
1089  return aPos;
1090 }
1091 
1092 
1093 CellPos SdrTableObj::getNextRow( const CellPos& rPos, bool bEdgeTravel ) const
1094 {
1095  CellPos aPos( rPos );
1096 
1097  if( mpImpl.is() )
1098  {
1099  CellRef xCell( mpImpl->getCell( rPos ) );
1100  if( xCell.is() )
1101  {
1102  if( xCell->isMerged() )
1103  {
1104  findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow );
1105  xCell = mpImpl->getCell(aPos);
1106  aPos.mnCol = rPos.mnCol;
1107  }
1108 
1109  if( xCell.is() )
1110  aPos.mnRow += xCell->getRowSpan();
1111 
1112  if( aPos.mnRow < mpImpl->mxTable->getRowCount() )
1113  return aPos;
1114 
1115  if( bEdgeTravel && (aPos.mnCol + 1) < mpImpl->mxTable->getColumnCount() )
1116  {
1117  aPos.mnRow = 0;
1118  aPos.mnCol += 1;
1119 
1120  while( aPos.mnCol < mpImpl->mxTable->getColumnCount() )
1121  {
1122  xCell = mpImpl->getCell( aPos );
1123  if( xCell.is() && !xCell->isMerged() )
1124  return aPos;
1125  aPos.mnCol += 1;
1126  }
1127  }
1128  }
1129  }
1130 
1131  // last position reached, no more traveling possible
1132  return rPos;
1133 }
1134 
1135 
1137 {
1138  if( mpImpl.is())
1139  {
1140  return mpImpl->maTableStyle;
1141  }
1142  else
1143  {
1144  static TableStyleSettings aTmp;
1145  return aTmp;
1146  }
1147 }
1148 
1149 
1151 {
1152  if( mpImpl.is() )
1153  {
1154  mpImpl->maTableStyle = rStyle;
1155  mpImpl->update();
1156  }
1157 }
1158 
1159 
1160 TableHitKind SdrTableObj::CheckTableHit( const Point& rPos, sal_Int32& rnX, sal_Int32& rnY, const sal_uInt16 aTol ) const
1161 {
1162  if( !mpImpl.is() || !mpImpl->mxTable.is() )
1163  return TableHitKind::NONE;
1164 
1165  rnX = 0;
1166  rnY = 0;
1167 
1168  const sal_Int32 nColCount = mpImpl->getColumnCount();
1169  const sal_Int32 nRowCount = mpImpl->getRowCount();
1170 
1171  sal_Int32 nX = rPos.X() - maRect.Left();
1172  sal_Int32 nY = rPos.Y() - maRect.Top();
1173 
1174  if( (nX < 0) || (nX > maRect.GetWidth()) || (nY < 0) || (nY > maRect.GetHeight() ) )
1175  return TableHitKind::NONE;
1176 
1177  // get vertical edge number and check for a hit
1178  const bool bRTL = (GetWritingMode() == WritingMode_RL_TB);
1179  bool bVrtHit = false;
1180  if( !bRTL )
1181  {
1182  while( rnX <= nColCount )
1183  {
1184  if( nX - aTol <= 0 )
1185  {
1186  bVrtHit = true;
1187  break;
1188  }
1189 
1190  if( rnX == nColCount )
1191  break;
1192 
1193  nX -= mpImpl->mpLayouter->getColumnWidth( rnX );
1194  if( nX < 0 )
1195  break;
1196  rnX++;
1197  }
1198  }
1199  else
1200  {
1201  rnX = nColCount;
1202  while( rnX >= 0 )
1203  {
1204  if( nX - aTol <= 0 )
1205  {
1206  bVrtHit = true;
1207  break;
1208  }
1209 
1210  if( rnX == 0 )
1211  break;
1212 
1213  rnX--;
1214  nX -= mpImpl->mpLayouter->getColumnWidth( rnX );
1215  if( nX < 0 )
1216  break;
1217  }
1218  }
1219 
1220  // rnX is now the edge number left to the pointer, if it was hit bHrzHit is also true
1221 
1222  // get vertical edge number and check for a hit
1223  bool bHrzHit = false;
1224  while( rnY <= nRowCount )
1225  {
1226  if( nY - aTol <= 0 )
1227  {
1228  bHrzHit = true;
1229  break;
1230  }
1231 
1232  if( rnY == nRowCount )
1233  break;
1234 
1235  nY -= mpImpl->mpLayouter->getRowHeight(rnY);
1236  if( nY < 0 )
1237  break;
1238  rnY++;
1239  }
1240 
1241  // rnY is now the edge number above the pointer, if it was hit bVrtHit is also true
1242 
1243  if( bVrtHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, false ) )
1245 
1246  if( bHrzHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, true ) )
1248 
1249  CellRef xCell( mpImpl->getCell( CellPos( rnX, rnY ) ) );
1250  if( xCell.is() && xCell->isMerged() )
1251  findMergeOrigin( mpImpl->mxTable.get(), rnX, rnY, rnX, rnY );
1252 
1253  if( xCell.is() )
1254  {
1255  nX += mpImpl->mpLayouter->getColumnWidth( rnX );
1256  //Fix for fdo#62673 : non-editable cell in table on cell merge
1257  sal_Int32 i=0;
1258  while(xCell.is() && xCell->isMerged())
1259  {
1260  nX += mpImpl->mpLayouter->getColumnWidth( rnX+i );
1261  i++;
1262  if(rnX+i < nColCount)
1263  xCell=mpImpl->getCell( CellPos( rnX+i, rnY) );
1264  else
1265  break;
1266  }
1267 
1268  if( nX < xCell->GetTextLeftDistance() )
1269  return TableHitKind::Cell;
1270  }
1271 
1273 }
1274 
1276 {
1277  return getActiveCell()->GetItemSet();
1278 }
1279 
1280 void SdrTableObj::setTableStyle( const Reference< XIndexAccess >& xTableStyle )
1281 {
1282  if( mpImpl.is() && (mpImpl->mxTableStyle != xTableStyle) )
1283  {
1284  mpImpl->disconnectTableStyle();
1285  mpImpl->mxTableStyle = xTableStyle;
1286  mpImpl->connectTableStyle();
1287  mpImpl->update();
1288  }
1289 }
1290 
1291 
1292 const Reference< XIndexAccess >& SdrTableObj::getTableStyle() const
1293 {
1294  if( mpImpl.is() )
1295  {
1296  return mpImpl->mxTableStyle;
1297  }
1298  else
1299  {
1300  static Reference< XIndexAccess > aTmp;
1301  return aTmp;
1302  }
1303 }
1304 
1305 
1306 // text stuff
1307 
1308 
1311 {
1312  return dynamic_cast< SdrText* >( getActiveCell().get() );
1313 }
1314 
1315 
1317 SdrText* SdrTableObj::getText( sal_Int32 nIndex ) const
1318 {
1319  if( mpImpl->mxTable.is() )
1320  {
1321  const sal_Int32 nColCount = mpImpl->getColumnCount();
1322  if( nColCount )
1323  {
1324  CellPos aPos( nIndex % nColCount, nIndex / nColCount );
1325 
1326  CellRef xCell( mpImpl->getCell( aPos ) );
1327  return dynamic_cast< SdrText* >( xCell.get() );
1328  }
1329  }
1330  return nullptr;
1331 }
1332 
1333 
1335 sal_Int32 SdrTableObj::getTextCount() const
1336 {
1337  if( mpImpl->mxTable.is() )
1338  {
1339  const sal_Int32 nColCount = mpImpl->getColumnCount();
1340  const sal_Int32 nRowCount = mpImpl->getRowCount();
1341 
1342  return nColCount * nRowCount;
1343  }
1344  else
1345  {
1346  return 0;
1347  }
1348 }
1349 
1350 
1352 void SdrTableObj::setActiveText( sal_Int32 nIndex )
1353 {
1354  if( mpImpl.is() && mpImpl->mxTable.is() )
1355  {
1356  const sal_Int32 nColCount = mpImpl->mxTable->getColumnCount();
1357  if( nColCount )
1358  {
1359  CellPos aPos( nIndex % nColCount, nIndex / nColCount );
1360  if( isValid( aPos ) )
1361  setActiveCell( aPos );
1362  }
1363  }
1364 }
1365 
1366 
1368 sal_Int32 SdrTableObj::CheckTextHit(const Point& rPnt) const
1369 {
1370  if( mpImpl.is() && mpImpl->mxTable.is() )
1371  {
1372  CellPos aPos;
1373  if( CheckTableHit( rPnt, aPos.mnCol, aPos.mnRow ) == TableHitKind::CellTextArea )
1374  return aPos.mnRow * mpImpl->mxTable->getColumnCount() + aPos.mnCol;
1375  }
1376 
1377  return 0;
1378 }
1379 
1381 {
1382  if( mpImpl.is() && (mpImpl->getCell( mpImpl->maEditPos ).get() == &rCell) )
1383  return pEdtOutl;
1384  else
1385  return nullptr;
1386 }
1387 
1389 {
1390  assert(mpImpl.is() && mpImpl->mpLayouter && "getTableLayouter() error: no mpImpl or mpLayouter (!)");
1391  return *(mpImpl->mpLayouter);
1392 }
1393 
1395 {
1396  return true;
1397 }
1398 
1400 {
1401  return true;
1402 }
1403 
1405 {
1406  return true;
1407 }
1408 
1410 {
1411  return pEdtOutl && mpImpl.is() && (rPos == mpImpl->maEditPos);
1412 }
1413 
1414 
1416 {
1417  if( (pEditStatus->GetStatusWord() & EditStatusFlags::TextHeightChanged) && mpImpl.is() && mpImpl->mpLayouter )
1418  {
1419  tools::Rectangle aRect0( maRect );
1420  maRect = maLogicRect;
1421  mpImpl->LayoutTable( maRect, false, false );
1422  SetRectsDirty();
1423  ActionChanged();
1425  if (aRect0 != maRect)
1427  }
1428 }
1429 
1430 
1432 {
1433  rInfo.bResizeFreeAllowed=true;
1434  rInfo.bResizePropAllowed=true;
1435  rInfo.bRotateFreeAllowed=false;
1436  rInfo.bRotate90Allowed =false;
1437  rInfo.bMirrorFreeAllowed=false;
1438  rInfo.bMirror45Allowed =false;
1439  rInfo.bMirror90Allowed =false;
1440 
1441  // allow transparence
1442  rInfo.bTransparenceAllowed = true;
1443 
1444  rInfo.bShearAllowed =false;
1445  rInfo.bEdgeRadiusAllowed=false;
1446  rInfo.bCanConvToPath =false;
1447  rInfo.bCanConvToPoly =false;
1448  rInfo.bCanConvToPathLineToArea=false;
1449  rInfo.bCanConvToPolyLineToArea=false;
1450  rInfo.bCanConvToContour = false;
1451 }
1452 
1454 {
1455  return OBJ_TABLE;
1456 }
1457 
1458 void SdrTableObj::TakeTextRect( SdrOutliner& rOutliner, tools::Rectangle& rTextRect, bool bNoEditText, tools::Rectangle* pAnchorRect, bool /*bLineWidth*/ ) const
1459 {
1460  if( mpImpl.is() )
1461  TakeTextRect( mpImpl->maEditPos, rOutliner, rTextRect, bNoEditText, pAnchorRect );
1462 }
1463 
1464 
1465 void SdrTableObj::TakeTextRect( const CellPos& rPos, SdrOutliner& rOutliner, tools::Rectangle& rTextRect, bool bNoEditText, tools::Rectangle* pAnchorRect ) const
1466 {
1467  if( !mpImpl.is())
1468  return;
1469 
1470  CellRef xCell( mpImpl->getCell( rPos ) );
1471  if( !xCell.is() )
1472  return;
1473 
1474  tools::Rectangle aAnkRect;
1475  TakeTextAnchorRect( rPos, aAnkRect );
1476 
1477  SdrTextVertAdjust eVAdj=xCell->GetTextVerticalAdjust();
1478 
1479  EEControlBits nStat0=rOutliner.GetControlWord();
1480  nStat0 |= EEControlBits::AUTOPAGESIZE;
1481  rOutliner.SetControlWord(nStat0);
1482  rOutliner.SetMinAutoPaperSize(Size());
1483  rOutliner.SetMaxAutoPaperSize(aAnkRect.GetSize());
1484  rOutliner.SetPaperSize(aAnkRect.GetSize());
1485 
1486  // #103516# New try with _BLOCK for hor and ver after completely
1487  // supporting full width for vertical text.
1488 // if( SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
1489 // {
1490  rOutliner.SetMinAutoPaperSize(Size(aAnkRect.GetWidth(), 0));
1491 // }
1492 // else if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
1493 // {
1494 // rOutliner.SetMinAutoPaperSize(Size(0, aAnkRect.GetHeight()));
1495 // }
1496 
1497 
1498  // set text at outliner, maybe from edit outliner
1499  OutlinerParaObject* pPara= xCell->GetOutlinerParaObject();
1500  if (pEdtOutl && !bNoEditText && mpImpl->mxActiveCell == xCell )
1501  pPara=pEdtOutl->CreateParaObject().release();
1502 
1503  if (pPara)
1504  {
1505  const bool bHitTest(&getSdrModelFromSdrObject().GetHitTestOutliner() == &rOutliner);
1506  const SdrTextObj* pTestObj(rOutliner.GetTextObj());
1507 
1508  if( !pTestObj || !bHitTest || (pTestObj != this) || (pTestObj->GetOutlinerParaObject() != xCell->GetOutlinerParaObject()) )
1509  {
1510  if( bHitTest ) // #i33696# take back fix #i27510#
1511  rOutliner.SetTextObj( this );
1512 
1513  rOutliner.SetUpdateMode(true);
1514  rOutliner.SetText(*pPara);
1515  }
1516  }
1517  else
1518  {
1519  rOutliner.SetTextObj( nullptr );
1520  }
1521 
1522  if (pEdtOutl && !bNoEditText && pPara && mpImpl->mxActiveCell == xCell )
1523  delete pPara;
1524 
1525  rOutliner.SetUpdateMode(true);
1526  rOutliner.SetControlWord(nStat0);
1527 
1528  Point aTextPos(aAnkRect.TopLeft());
1529  Size aTextSiz(rOutliner.GetPaperSize());
1531  {
1532  tools::Long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
1533  if (eVAdj==SDRTEXTVERTADJUST_CENTER)
1534  aTextPos.AdjustY(nFreeHgt/2 );
1535  if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1536  aTextPos.AdjustY(nFreeHgt );
1537  }
1538 
1539  if (pAnchorRect)
1540  *pAnchorRect=aAnkRect;
1541 
1542  rTextRect=tools::Rectangle(aTextPos,aTextSiz);
1543 }
1544 
1545 
1547 {
1548  if( mpImpl.is() )
1549  {
1550  if( !mpImpl->mxActiveCell.is() )
1551  {
1552  CellPos aPos;
1553  const_cast< SdrTableObj* >(this)->setActiveCell( aPos );
1554  }
1555  return mpImpl->mxActiveCell;
1556  }
1557  else
1558  {
1559  static CellRef xCell;
1560  return xCell;
1561  }
1562 }
1563 
1564 
1566 {
1567  return mpImpl.is() ? mpImpl->getColumnCount() : 0;
1568 }
1569 
1570 sal_Int32 SdrTableObj::getRowCount() const
1571 {
1572  return mpImpl.is() ? mpImpl->getRowCount() : 0;
1573 }
1574 
1575 void SdrTableObj::changeEdge(bool bHorizontal, int nEdge, sal_Int32 nOffset)
1576 {
1577  if (mpImpl.is())
1578  mpImpl->DragEdge(bHorizontal, nEdge, nOffset);
1579 }
1580 
1582 {
1583  if( !(mpImpl.is() && mpImpl->mxTable.is()) )
1584  return;
1585 
1586  try
1587  {
1588  mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
1589  if( mpImpl->mxActiveCell.is() && mpImpl->mxActiveCell->isMerged() )
1590  {
1591  CellPos aOrigin;
1592  findMergeOrigin( mpImpl->mxTable.get(), rPos.mnCol, rPos.mnRow, aOrigin.mnCol, aOrigin.mnRow );
1593  mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( aOrigin.mnCol, aOrigin.mnRow ).get() ) );
1594  mpImpl->maEditPos = aOrigin;
1595  }
1596  else
1597  {
1598  mpImpl->maEditPos = rPos;
1599  }
1600  }
1601  catch( Exception& )
1602  {
1603  TOOLS_WARN_EXCEPTION("svx.table", "");
1604  }
1605 }
1606 
1607 
1609 {
1610  rPos = mpImpl->maEditPos;
1611 }
1612 
1613 
1614 void SdrTableObj::getCellBounds( const CellPos& rPos, ::tools::Rectangle& rCellRect )
1615 {
1616  if( mpImpl.is() )
1617  {
1618  CellRef xCell( mpImpl->getCell( rPos ) );
1619  if( xCell.is() )
1620  rCellRect = xCell->getCellRect();
1621  }
1622 }
1623 
1624 
1625 void SdrTableObj::TakeTextAnchorRect(tools::Rectangle& rAnchorRect) const
1626 {
1627  if( mpImpl.is() )
1628  TakeTextAnchorRect( mpImpl->maEditPos, rAnchorRect );
1629 }
1630 
1631 
1632 void SdrTableObj::TakeTextAnchorRect( const CellPos& rPos, tools::Rectangle& rAnchorRect ) const
1633 {
1634  tools::Rectangle aAnkRect(maRect);
1635 
1636  if( mpImpl.is() )
1637  {
1638  CellRef xCell( mpImpl->getCell( rPos ) );
1639  if( xCell.is() )
1640  xCell->TakeTextAnchorRect( aAnkRect );
1641  }
1642 
1643  ImpJustifyRect(aAnkRect);
1644  rAnchorRect=aAnkRect;
1645 }
1646 
1647 
1648 void SdrTableObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, tools::Rectangle* pViewInit, tools::Rectangle* pViewMin) const
1649 {
1650  if( mpImpl.is() )
1651  TakeTextEditArea( mpImpl->maEditPos, pPaperMin, pPaperMax, pViewInit, pViewMin );
1652 }
1653 
1654 
1655 void SdrTableObj::TakeTextEditArea( const CellPos& rPos, Size* pPaperMin, Size* pPaperMax, tools::Rectangle* pViewInit, tools::Rectangle* pViewMin ) const
1656 {
1657  Size aPaperMin,aPaperMax;
1658  tools::Rectangle aViewInit;
1659  TakeTextAnchorRect( rPos, aViewInit );
1660 
1661  Size aAnkSiz(aViewInit.GetSize());
1662  aAnkSiz.AdjustWidth( -1 ); aAnkSiz.AdjustHeight( -1 ); // because GetSize() increments by one
1663 
1664  Size aMaxSiz(aAnkSiz.Width(),1000000);
1665  Size aTmpSiz(getSdrModelFromSdrObject().GetMaxObjSize());
1666  if (aTmpSiz.Height()!=0)
1667  aMaxSiz.setHeight(aTmpSiz.Height() );
1668 
1669  CellRef xCell( mpImpl->getCell( rPos ) );
1670  SdrTextVertAdjust eVAdj = xCell.is() ? xCell->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_TOP;
1671 
1672  aPaperMax=aMaxSiz;
1673 
1674  aPaperMin.setWidth( aAnkSiz.Width() );
1675 
1676  if (pViewMin!=nullptr)
1677  {
1678  *pViewMin=aViewInit;
1679  tools::Long nYFree=aAnkSiz.Height()-aPaperMin.Height();
1680 
1681  if (eVAdj==SDRTEXTVERTADJUST_TOP)
1682  {
1683  pViewMin->AdjustBottom( -nYFree );
1684  }
1685  else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1686  {
1687  pViewMin->AdjustTop(nYFree );
1688  }
1689  else
1690  {
1691  pViewMin->AdjustTop(nYFree/2 );
1692  pViewMin->SetBottom(pViewMin->Top()+aPaperMin.Height() );
1693  }
1694  }
1695 
1696 
1697  if(IsVerticalWriting())
1698  aPaperMin.setWidth( 0 );
1699  else
1700  aPaperMin.setHeight( 0 );
1701 
1702  if (pPaperMin!=nullptr) *pPaperMin=aPaperMin;
1703  if (pPaperMax!=nullptr) *pPaperMax=aPaperMax;
1704  if (pViewInit!=nullptr) *pViewInit=aViewInit;
1705 }
1706 
1707 
1709 {
1710  EEAnchorMode eRet=EEAnchorMode::TopLeft;
1711  CellRef xCell( getActiveCell() );
1712  if( xCell.is() )
1713  {
1714  SdrTextVertAdjust eV=xCell->GetTextVerticalAdjust();
1715 
1716  {
1717  if (eV==SDRTEXTVERTADJUST_TOP)
1718  {
1719  eRet=EEAnchorMode::TopLeft;
1720  }
1721  else if (eV==SDRTEXTVERTADJUST_BOTTOM)
1722  {
1723  eRet=EEAnchorMode::BottomLeft;
1724  }
1725  else
1726  {
1727  eRet=EEAnchorMode::VCenterLeft;
1728  }
1729  }
1730  }
1731  return eRet;
1732 }
1733 
1734 
1736 {
1737  OUStringBuffer sName(SvxResId(STR_ObjNameSingulTable));
1738 
1739  OUString aName(GetName());
1740  if (!aName.isEmpty())
1741  {
1742  sName.append(' ');
1743  sName.append('\'');
1744  sName.append(aName);
1745  sName.append('\'');
1746  }
1747 
1748  return sName.makeStringAndClear();
1749 }
1750 
1751 
1753 {
1754  return SvxResId(STR_ObjNamePluralTable);
1755 }
1756 
1757 
1759 {
1760  return CloneHelper< SdrTableObj >(rTargetModel);
1761 }
1762 
1764 {
1765  if( this == &rObj )
1766  {
1767  return *this;
1768  }
1769 
1770  // call parent
1771  // before SdrObject::operator= was called which is wrong from
1772  // the derivation hierarchy and may leave quite some entries
1773  // uninitialized. Changed to SdrTextObj::operator=, but had to adapt
1774  // usage of pNewOutlinerParaObject/mpText there due to nullptr access
1775  SdrTextObj::operator=(rObj);
1776 
1777  TableModelNotifyGuard aGuard( mpImpl.is() ? mpImpl->mxTable.get() : nullptr );
1778 
1779  maLogicRect = rObj.maLogicRect;
1780  maRect = rObj.maRect;
1781  aGeo = rObj.aGeo;
1782  eTextKind = rObj.eTextKind;
1783  bTextFrame = rObj.bTextFrame;
1784  aTextSize = rObj.aTextSize;
1786  bNoShear = rObj.bNoShear;
1788 
1789  // use SdrTableObjImpl::operator= now to
1790  // copy model data and other stuff (see there)
1791  *mpImpl = *rObj.mpImpl;
1792 
1793  return *this;
1794 }
1795 
1796 
1798 {
1799  return maRect;
1800 }
1801 
1802 
1804 {
1805  NbcSetLogicRect( rRect );
1806 }
1807 
1808 
1810 {
1811  return maLogicRect;
1812 }
1813 
1814 
1816 {
1817 }
1818 
1819 
1821 {
1822  if( pEdtOutl != nullptr )
1823  return false;
1824 
1825  pEdtOutl=&rOutl;
1826 
1827  mbInEditMode = true;
1828 
1829  rOutl.Init( OutlinerMode::TextObject );
1830  rOutl.SetRefDevice(getSdrModelFromSdrObject().GetRefDevice());
1831 
1832  bool bUpdateMode=rOutl.GetUpdateMode();
1833  if (bUpdateMode) rOutl.SetUpdateMode(false);
1834  Size aPaperMin;
1835  Size aPaperMax;
1836  tools::Rectangle aEditArea;
1837  TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,nullptr);
1838 
1839  rOutl.SetMinAutoPaperSize(aPaperMin);
1840  rOutl.SetMaxAutoPaperSize(aPaperMax);
1841  rOutl.SetPaperSize(aPaperMax);
1842 
1843  if (bUpdateMode) rOutl.SetUpdateMode(true);
1844 
1845  EEControlBits nStat=rOutl.GetControlWord();
1846  nStat |= EEControlBits::AUTOPAGESIZE;
1847  nStat &=~EEControlBits::STRETCHING;
1848  rOutl.SetControlWord(nStat);
1849 
1851  if(pPara)
1852  rOutl.SetText(*pPara);
1853 
1854  rOutl.UpdateFields();
1855  rOutl.ClearModifyFlag();
1856 
1857  return true;
1858 }
1859 
1860 
1862 {
1863 
1864  if (getSdrModelFromSdrObject().IsUndoEnabled() && !mpImpl->maUndos.empty())
1865  {
1866  // These actions should be on the undo stack after text edit.
1867  for (std::unique_ptr<SdrUndoAction>& pAction : mpImpl->maUndos)
1868  getSdrModelFromSdrObject().AddUndo( std::move(pAction));
1869  mpImpl->maUndos.clear();
1870 
1871  getSdrModelFromSdrObject().AddUndo(getSdrModelFromSdrObject().GetSdrUndoFactory().CreateUndoGeoObject(*this));
1872  }
1873 
1874  if(rOutl.IsModified())
1875  {
1876  std::unique_ptr<OutlinerParaObject> pNewText;
1877  Paragraph* p1stPara = rOutl.GetParagraph( 0 );
1878  sal_Int32 nParaCnt = rOutl.GetParagraphCount();
1879 
1880  if(p1stPara)
1881  {
1882  // to remove the grey field background
1883  rOutl.UpdateFields();
1884 
1885  // create new text object
1886  pNewText = rOutl.CreateParaObject( 0, nParaCnt );
1887  }
1888  SetOutlinerParaObject(std::move(pNewText));
1889  }
1890 
1891  pEdtOutl = nullptr;
1892  rOutl.Clear();
1893  EEControlBits nStat = rOutl.GetControlWord();
1894  nStat &= ~EEControlBits::AUTOPAGESIZE;
1895  rOutl.SetControlWord(nStat);
1896 
1897  mbInEditMode = false;
1898 }
1899 
1900 
1902 {
1903  CellRef xCell( getActiveCell() );
1904  if( xCell.is() )
1905  return xCell->GetOutlinerParaObject();
1906  else
1907  return nullptr;
1908 }
1909 
1910 
1911 void SdrTableObj::NbcSetOutlinerParaObject( std::unique_ptr<OutlinerParaObject> pTextObject)
1912 {
1913  CellRef xCell( getActiveCell() );
1914  if( !xCell.is() )
1915  return;
1916 
1917  // Update HitTestOutliner
1918  const SdrTextObj* pTestObj(getSdrModelFromSdrObject().GetHitTestOutliner().GetTextObj());
1919 
1920  if(pTestObj && pTestObj->GetOutlinerParaObject() == xCell->GetOutlinerParaObject())
1921  {
1923  }
1924 
1925  xCell->SetOutlinerParaObject( std::move(pTextObject) );
1926  SetTextSizeDirty();
1928 }
1929 
1930 
1932 {
1933  maLogicRect=rRect;
1935  const bool bWidth = maLogicRect.getWidth() != maRect.getWidth();
1936  const bool bHeight = maLogicRect.getHeight() != maRect.getHeight();
1937  maRect = maLogicRect;
1938  if (mpImpl->mbSkipChangeLayout)
1939  // Avoid distributing newly available space between existing cells.
1941  else
1942  NbcAdjustTextFrameWidthAndHeight(!bHeight, !bWidth);
1943  SetRectsDirty();
1944 }
1945 
1946 
1947 void SdrTableObj::AdjustToMaxRect( const tools::Rectangle& rMaxRect, bool /* bShrinkOnly = false */ )
1948 {
1949  tools::Rectangle aAdjustRect( rMaxRect );
1950  aAdjustRect.setHeight( GetLogicRect().getHeight() );
1951  SetLogicRect( aAdjustRect );
1952 }
1953 
1954 
1955 void SdrTableObj::NbcMove(const Size& rSiz)
1956 {
1957  maLogicRect.Move(rSiz);
1958  SdrTextObj::NbcMove( rSiz );
1959  if( mpImpl.is() )
1960  mpImpl->UpdateCells( maRect );
1961 }
1962 
1963 
1964 void SdrTableObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1965 {
1966  tools::Rectangle aOldRect( maLogicRect );
1967  ResizeRect(maLogicRect,rRef,xFact,yFact);
1968 
1969  maRect = maLogicRect;
1971  SetRectsDirty();
1972 }
1973 
1974 
1976 {
1977  tools::Rectangle aNewRect(maLogicRect);
1978  bool bRet=AdjustTextFrameWidthAndHeight(aNewRect);
1979  if (bRet)
1980  {
1981  tools::Rectangle aBoundRect0;
1982  if (pUserCall!=nullptr)
1983  aBoundRect0=GetLastBoundRect();
1984  maRect = aNewRect;
1985  SetRectsDirty();
1986  SetChanged();
1989  }
1990  return bRet;
1991 }
1992 
1993 
1994 bool SdrTableObj::AdjustTextFrameWidthAndHeight(tools::Rectangle& rR, bool bHeight, bool bWidth) const
1995 {
1996  if(rR.IsEmpty() || !mpImpl.is() || !mpImpl->mxTable.is())
1997  return false;
1998 
1999  tools::Rectangle aRectangle( rR );
2000  mpImpl->LayoutTable( aRectangle, !bWidth, !bHeight );
2001 
2002  if( aRectangle != rR )
2003  {
2004  rR = aRectangle;
2005  return true;
2006  }
2007  else
2008  {
2009  return false;
2010  }
2011 }
2012 
2013 
2015 {
2017 }
2018 
2019 
2021 {
2023  return rModeItem.GetValue() == css::text::WritingMode_TB_RL;
2024 }
2025 
2026 
2028 {
2029  if(bVertical != IsVerticalWriting() )
2030  {
2031  SvxWritingModeItem aModeItem( css::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION );
2032  SetObjectItem( aModeItem );
2033  }
2034 }
2035 
2036 
2038 {
2039  SfxStyleSheet* pStyle = GetStyleSheet();
2040  if ( !pStyle )
2041  return WritingMode_LR_TB;
2042 
2043  WritingMode eWritingMode = WritingMode_LR_TB;
2044  const SfxItemSet &rSet = pStyle->GetItemSet();
2045  const SfxPoolItem *pItem;
2046 
2047  if ( rSet.GetItemState( SDRATTR_TEXTDIRECTION, false, &pItem ) == SfxItemState::SET )
2048  eWritingMode = static_cast< const SvxWritingModeItem * >( pItem )->GetValue();
2049 
2050  if ( ( eWritingMode != WritingMode_TB_RL ) &&
2051  ( rSet.GetItemState( EE_PARA_WRITINGDIR, false, &pItem ) == SfxItemState::SET ) )
2052  {
2053  if ( static_cast< const SvxFrameDirectionItem * >( pItem )->GetValue() == SvxFrameDirection::Horizontal_LR_TB )
2054  eWritingMode = WritingMode_LR_TB;
2055  else
2056  eWritingMode = WritingMode_RL_TB;
2057  }
2058 
2059  return eWritingMode;
2060 }
2061 
2063 {
2064  mpImpl->maUndos.push_back(std::unique_ptr<SdrUndoAction>(pUndo));
2065 }
2066 
2067 void SdrTableObj::SetSkipChangeLayout(bool bSkipChangeLayout)
2068 {
2069  mpImpl->mbSkipChangeLayout = bSkipChangeLayout;
2070 }
2071 
2073 {
2074  return pEdtOutl && pEdtOutl->IsModified();
2075 }
2076 
2078 {
2079  return false;
2080 }
2081 
2082 sal_uInt32 SdrTableObj::GetHdlCount() const
2083 {
2084  sal_uInt32 nCount = SdrTextObj::GetHdlCount();
2085  const sal_Int32 nRowCount = mpImpl->getRowCount();
2086  const sal_Int32 nColCount = mpImpl->getColumnCount();
2087 
2088  if( nRowCount && nColCount )
2089  nCount += nRowCount + nColCount + 2 + 1;
2090 
2091  return nCount;
2092 }
2093 
2095 {
2096  const sal_Int32 nRowCount = mpImpl->getRowCount();
2097  const sal_Int32 nColCount = mpImpl->getColumnCount();
2098 
2099  // first add row handles
2100  std::vector<TableEdgeHdl*> aRowEdges(nRowCount + 1);
2101  for (auto const & rEdge : mpImpl->mpLayouter->getHorizontalEdges())
2102  {
2103  Point aPoint(maRect.TopLeft());
2104  aPoint.AdjustY(rEdge.nPosition);
2105 
2106  std::unique_ptr<TableEdgeHdl> pHdl(new TableEdgeHdl(aPoint, true, rEdge.nMin, rEdge.nMax, nColCount + 1));
2107  pHdl->SetPointNum(rEdge.nIndex);
2108  aRowEdges[rEdge.nIndex] = pHdl.get();
2109  rHdlList.AddHdl(std::move(pHdl));
2110  }
2111 
2112  // second add column handles
2113  std::vector<TableEdgeHdl*> aColEdges(nColCount + 1);
2114  for (auto const & rEdge : mpImpl->mpLayouter->getVerticalEdges())
2115  {
2116  Point aPoint(maRect.TopLeft());
2117  aPoint.AdjustX(rEdge.nPosition);
2118 
2119  std::unique_ptr<TableEdgeHdl> pHdl(new TableEdgeHdl(aPoint, false, rEdge.nMin, rEdge.nMax, nRowCount + 1));
2120  pHdl->SetPointNum(rEdge.nIndex);
2121  aColEdges[rEdge.nIndex] = pHdl.get();
2122  rHdlList.AddHdl(std::move(pHdl));
2123  }
2124 
2125  // now add visible edges to row and column handles
2126  if( mpImpl->mpLayouter )
2127  {
2128  TableLayouter& rLayouter = *mpImpl->mpLayouter;
2129 
2130  sal_Int32 nY = 0;
2131 
2132  for( sal_Int32 nRow = 0; nRow <= nRowCount; ++nRow )
2133  {
2134  const sal_Int32 nRowHeight = (nRow == nRowCount) ? 0 : rLayouter.getRowHeight(nRow);
2135  sal_Int32 nX = 0;
2136 
2137  for( sal_Int32 nCol = 0; nCol <= nColCount; ++nCol )
2138  {
2139  const sal_Int32 nColWidth = (nCol == nColCount) ? 0 : rLayouter.getColumnWidth(nCol);
2140 
2141  if( nRowHeight > 0 )
2142  {
2143  if( rLayouter.isEdgeVisible( nCol, nRow, false ) )
2144  aColEdges[nCol]->SetEdge( nRow, nY, nY + nRowHeight, (rLayouter.getBorderLine( nCol, nRow, false ) == nullptr) ? Visible : Invisible);
2145  }
2146 
2147  if( nColWidth > 0 )
2148  {
2149  if( rLayouter.isEdgeVisible( nCol, nRow, true ) )
2150  aRowEdges[nRow]->SetEdge( nCol, nX, nX + nColWidth, (rLayouter.getBorderLine( nCol, nRow, true ) == nullptr) ? Visible : Invisible);
2151  }
2152 
2153  nX += nColWidth;
2154  }
2155 
2156  nY += nRowHeight;
2157  }
2158  }
2159 
2160  // add remaining handles
2161  SdrHdlList tempList(nullptr);
2162  tempList.AddHdl( std::make_unique<TableBorderHdl>( maRect, !IsTextEditActive() ) );
2163  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.TopLeft(),SdrHdlKind::UpperLeft) );
2164  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.TopCenter(),SdrHdlKind::Upper) );
2165  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.TopRight(),SdrHdlKind::UpperRight) );
2166  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.LeftCenter(),SdrHdlKind::Left) );
2167  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.RightCenter(),SdrHdlKind::Right) );
2168  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.BottomLeft(),SdrHdlKind::LowerLeft) );
2169  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.BottomCenter(),SdrHdlKind::Lower) );
2170  tempList.AddHdl( std::make_unique<SdrHdl>(maRect.BottomRight(),SdrHdlKind::LowerRight) );
2171  for( size_t nHdl = 0; nHdl < tempList.GetHdlCount(); ++nHdl )
2172  tempList.GetHdl(nHdl)->SetMoveOutside(true);
2173  tempList.MoveTo(rHdlList);
2174 
2175  const size_t nHdlCount = rHdlList.GetHdlCount();
2176  for( size_t nHdl = 0; nHdl < nHdlCount; ++nHdl )
2177  rHdlList.GetHdl(nHdl)->SetObj(const_cast<SdrTableObj*>(this));
2178 }
2179 
2180 // Dragging
2181 
2183 {
2184  return true;
2185 }
2186 
2188 {
2189  const SdrHdl* pHdl = rDrag.GetHdl();
2190  const SdrHdlKind eHdl((pHdl == nullptr) ? SdrHdlKind::Move : pHdl->GetKind());
2191 
2192  switch( eHdl )
2193  {
2194  case SdrHdlKind::UpperLeft:
2195  case SdrHdlKind::Upper:
2197  case SdrHdlKind::Left:
2198  case SdrHdlKind::Right:
2199  case SdrHdlKind::LowerLeft:
2200  case SdrHdlKind::Lower:
2202  case SdrHdlKind::Move:
2203  {
2204  break;
2205  }
2206 
2207  case SdrHdlKind::User:
2208  {
2209  rDrag.SetEndDragChangesAttributes(false);
2210  rDrag.SetNoSnap();
2211  break;
2212  }
2213 
2214  default:
2215  {
2216  return false;
2217  }
2218  }
2219 
2220  return true;
2221 }
2222 
2224 {
2225  bool bRet(true);
2226  const SdrHdl* pHdl = rDrag.GetHdl();
2227  const SdrHdlKind eHdl((pHdl == nullptr) ? SdrHdlKind::Move : pHdl->GetKind());
2228 
2229  switch( eHdl )
2230  {
2231  case SdrHdlKind::UpperLeft:
2232  case SdrHdlKind::Upper:
2234  case SdrHdlKind::Left:
2235  case SdrHdlKind::Right:
2236  case SdrHdlKind::LowerLeft:
2237  case SdrHdlKind::Lower:
2239  {
2240  const tools::Rectangle aNewRectangle(ImpDragCalcRect(rDrag));
2241 
2242  if (aNewRectangle != maRect)
2243  {
2244  NbcSetLogicRect(aNewRectangle);
2245  }
2246 
2247  break;
2248  }
2249 
2250  case SdrHdlKind::Move:
2251  {
2252  NbcMove( Size( rDrag.GetDX(), rDrag.GetDY() ) );
2253  break;
2254  }
2255 
2256  case SdrHdlKind::User:
2257  {
2258  rDrag.SetEndDragChangesAttributes(false);
2259  rDrag.SetNoSnap();
2260  const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
2261 
2262  if( pEdgeHdl )
2263  {
2264  if( IsInserted() )
2265  {
2266  rDrag.SetEndDragChangesAttributes(true);
2267  rDrag.SetEndDragChangesLayout(true);
2268  }
2269 
2270  mpImpl->DragEdge( pEdgeHdl->IsHorizontalEdge(), pEdgeHdl->GetPointNum(), pEdgeHdl->GetValidDragOffset( rDrag ) );
2271  }
2272  break;
2273  }
2274 
2275  default:
2276  {
2277  bRet = false;
2278  }
2279  }
2280 
2281  return bRet;
2282 }
2283 
2285 {
2286  basegfx::B2DPolyPolygon aRetval;
2287  const SdrHdl* pHdl = rDrag.GetHdl();
2288 
2289  if( pHdl && (SdrHdlKind::User == pHdl->GetKind()) )
2290  {
2291  const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
2292 
2293  if( pEdgeHdl )
2294  {
2295  aRetval = pEdgeHdl->getSpecialDragPoly( rDrag );
2296  }
2297  }
2298 
2299  return aRetval;
2300 }
2301 
2302 
2303 // Create
2304 
2305 
2307 {
2308  rStat.SetOrtho4Possible();
2309  tools::Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
2310  aRect1.Justify();
2311  rStat.SetActionRect(aRect1);
2312  maRect = aRect1;
2313  return true;
2314 }
2315 
2316 
2318 {
2319  tools::Rectangle aRect1;
2320  rStat.TakeCreateRect(aRect1);
2321  ImpJustifyRect(aRect1);
2322  rStat.SetActionRect(aRect1);
2323  maRect = aRect1; // for ObjName
2325  bSnapRectDirty=true;
2326  return true;
2327 }
2328 
2329 
2331 {
2332  rStat.TakeCreateRect(maRect);
2334  return (eCmd==SdrCreateCmd::ForceEnd || rStat.GetPointCount()>=2);
2335 }
2336 
2338 {
2339 }
2340 
2341 
2343 {
2344  return true;
2345 }
2346 
2347 
2349 {
2350  tools::Rectangle aRect1;
2351  rDrag.TakeCreateRect(aRect1);
2352  aRect1.Justify();
2353 
2354  basegfx::B2DPolyPolygon aRetval;
2357  return aRetval;
2358 }
2359 
2360 
2362 {
2363  return PointerStyle::Cross;
2364 }
2365 
2366 
2368 {
2369  xNewCell = Cell::create( *this );
2370 }
2371 
2372 
2374 {
2375  return new TableObjectGeoData;
2376 }
2377 
2378 
2380 {
2381  DBG_ASSERT( dynamic_cast< TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2382  SdrTextObj::SaveGeoData (rGeo);
2383 
2384  static_cast<TableObjectGeoData &>(rGeo).maLogicRect = maLogicRect;
2385 }
2386 
2387 
2389 {
2390  DBG_ASSERT( dynamic_cast< const TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2391 
2392  maLogicRect = static_cast<const TableObjectGeoData &>(rGeo).maLogicRect;
2393 
2394  SdrTextObj::RestGeoData (rGeo);
2395 
2396  if( mpImpl.is() )
2397  mpImpl->LayoutTable(maRect, false, false);
2398  ActionChanged();
2399 }
2400 
2402 {
2403  if(!mpImpl.is())
2404  {
2405  return;
2406  }
2407 
2408  mpImpl->CropTableModelToSelection(rStart, rEnd);
2409 }
2410 
2411 void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 nLastColumn, const bool bOptimize, const bool bMinimize )
2412 {
2413  if( mpImpl.is() && mpImpl->mpLayouter )
2414  {
2415  TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
2416  mpImpl->mpLayouter->DistributeColumns( maRect, nFirstColumn, nLastColumn, bOptimize, bMinimize );
2417  }
2418 }
2419 
2420 
2421 void SdrTableObj::DistributeRows( sal_Int32 nFirstRow, sal_Int32 nLastRow, const bool bOptimize, const bool bMinimize )
2422 {
2423  if( mpImpl.is() && mpImpl->mpLayouter )
2424  {
2425  TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
2426  mpImpl->mpLayouter->DistributeRows( maRect, nFirstRow, nLastRow, bOptimize, bMinimize );
2427  }
2428 }
2429 
2430 
2432 {
2433  if( mpImpl.is() )
2434  {
2435  mpImpl->LayoutTable( maRect, false, false );
2436  }
2437 
2439 }
2440 
2441 
2443 {
2444  if( mpImpl.is() && mpImpl->mxTable.is() )
2445  mpImpl->mxTable->lockBroadcasts();
2446 }
2447 
2448 
2450 {
2451  if( mpImpl.is() && mpImpl->mxTable.is() )
2452  mpImpl->mxTable->unlockBroadcasts();
2453 }
2454 
2456 {
2457  xmlTextWriterStartElement(pWriter, BAD_CAST("SdrTableObj"));
2458  xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
2459 
2460  SdrObject::dumpAsXml(pWriter);
2461 
2462  mpImpl->dumpAsXml(pWriter);
2463 
2464  xmlTextWriterEndElement(pWriter);
2465 }
2466 
2467 bool SdrTableObj::createTableEdgesJson(boost::property_tree::ptree & rJsonRoot)
2468 {
2469  if (!mpImpl.is() || !mpImpl->mxTable.is())
2470  return false;
2471 
2473  boost::property_tree::ptree aTableColumns;
2474  {
2475  aTableColumns.put("tableOffset", convertMm100ToTwip(aRect.Left()));
2476 
2477  boost::property_tree::ptree aEntries;
2478  auto const & aEdges = mpImpl->mpLayouter->getVerticalEdges();
2479  for (auto & rEdge : aEdges)
2480  {
2481  if (rEdge.nIndex == 0)
2482  {
2483  aTableColumns.put("left", convertMm100ToTwip(rEdge.nPosition));
2484  }
2485  else if (rEdge.nIndex == sal_Int32(aEdges.size() - 1))
2486  {
2487  aTableColumns.put("right", convertMm100ToTwip(rEdge.nPosition));
2488  }
2489  else
2490  {
2491  boost::property_tree::ptree aEntry;
2492  aEntry.put("position", convertMm100ToTwip(rEdge.nPosition));
2493  aEntry.put("min", convertMm100ToTwip(rEdge.nPosition + rEdge.nMin));
2494  aEntry.put("max", convertMm100ToTwip(rEdge.nPosition + rEdge.nMax));
2495  aEntry.put("hidden", false);
2496  aEntries.push_back(std::make_pair("", aEntry));
2497  }
2498  }
2499  aTableColumns.push_back(std::make_pair("entries", aEntries));
2500  }
2501  rJsonRoot.add_child("columns", aTableColumns);
2502 
2503  boost::property_tree::ptree aTableRows;
2504  {
2505  aTableRows.put("tableOffset", convertMm100ToTwip(aRect.Top()));
2506 
2507  boost::property_tree::ptree aEntries;
2508  auto const & aEdges = mpImpl->mpLayouter->getHorizontalEdges();
2509  for (auto & rEdge : aEdges)
2510  {
2511  if (rEdge.nIndex == 0)
2512  {
2513  aTableRows.put("left", convertMm100ToTwip(rEdge.nPosition));
2514  }
2515  else if (rEdge.nIndex == sal_Int32(aEdges.size() - 1))
2516  {
2517  aTableRows.put("right", convertMm100ToTwip(rEdge.nPosition));
2518  }
2519  else
2520  {
2521  boost::property_tree::ptree aEntry;
2522  aEntry.put("position", convertMm100ToTwip(rEdge.nPosition));
2523  aEntry.put("min", convertMm100ToTwip(rEdge.nPosition + rEdge.nMin));
2524  aEntry.put("max", convertMm100ToTwip(rEdge.nPosition + rEdge.nMax));
2525  aEntry.put("hidden", false);
2526  aEntries.push_back(std::make_pair("", aEntry));
2527  }
2528  }
2529  aTableRows.push_back(std::make_pair("entries", aEntries));
2530  }
2531  rJsonRoot.add_child("rows", aTableRows);
2532  return true;
2533 }
2534 
2535 }
2536 
2537 /* 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
const int nColCount
void LayoutTable(tools::Rectangle &rArea, bool bFitWidth, bool bFitHeight)
Definition: svdotable.cxx:792
CellPos getNextRow(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:1093
virtual std::unique_ptr< sdr::properties::BaseProperties > CreateObjectSpecificProperties() override
Definition: svdotable.cxx:847
CellPos getRightCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:955
virtual OutlinerParaObject * GetOutlinerParaObject() const override
Definition: svdotable.cxx:1901
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdotable.cxx:2388
static sal_Int32 lastRowCount
Definition: svdotable.cxx:248
css::uno::Reference< css::table::XTable > getTable() const
Definition: svdotable.cxx:910
virtual bool NbcAdjustTextFrameWidthAndHeight(bool bHgt=true, bool bWdt=true)
Definition: svdotxat.cxx:239
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:854
tools::Long GetDX() const
Definition: svddrag.hxx:148
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdotable.cxx:856
constexpr sal_uInt16 SDRATTR_TABLE_FIRST(SDRATTR_CUSTOMSHAPE_LAST+1)
void setTableStyle(const css::uno::Reference< css::container::XIndexAccess > &xAutoFormatStyle)
Definition: svdotable.cxx:1280
struct _xmlTextWriter * xmlTextWriterPtr
sal_Int32 getRowCount() const
Definition: svdotable.cxx:787
CellPos getUpCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:970
void setWidth(tools::Long nWidth)
SdrObjUserCall * pUserCall
Definition: svdobj.hxx:874
tools::Long getWidth() const
tools::Long GetDY() const
Definition: svddrag.hxx:149
virtual bool IsAutoGrowWidth() const override
Definition: svdotable.cxx:1399
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:2373
GeoStat aGeo
Definition: svdotext.hxx:185
CellRef getCell(const CellPos &rPos) const
Definition: svdotable.cxx:757
SdrHdlKind
Definition: svdhdl.hxx:52
void SetPaperSize(const Size &rSize)
virtual bool beginSpecialDrag(SdrDragStat &rDrag) const override
Definition: svdotable.cxx:2187
tools::Long GetTextLeftDistance() const
Left inner spacing to borders.
Definition: svdotext.cxx:1750
bool isValid(const sdr::table::CellPos &rPos) const
Definition: svdotable.cxx:916
virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat &rDrag) const override
Polygon dragged by the user when creating the object.
Definition: svdotable.cxx:2348
basegfx::B2DPolyPolygon getSpecialDragPoly(const SdrDragStat &rDrag) const
long Long
void CropTableModelToSelection(const CellPos &rStart, const CellPos &rEnd)
Definition: svdotable.cxx:277
SdrOutliner * pEdtOutl
Definition: svdotext.hxx:196
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdotable.cxx:1964
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:2367
virtual void setActiveText(sal_Int32 nIndex) override
Changes the current active text.
Definition: svdotable.cxx:1352
virtual bool IsFontwork() const override
Definition: svdotable.cxx:2077
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:741
virtual void TakeTextEditArea(Size *pPaperMin, Size *pPaperMax, tools::Rectangle *pViewInit, tools::Rectangle *pViewMin) const override
Definition: svdotable.cxx:1648
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:1380
void CropTableModelToSelection(const CellPos &rStart, const CellPos &rEnd)
Definition: svdotable.cxx:2401
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: svdotable.cxx:1431
const sal_Int32 first_column_style
Definition: tabledesign.hxx:31
constexpr sal_uInt16 EE_ITEMS_END(EE_FEATURE_END)
tools::Long GetWidth() const
sal_Int32 GetParagraphCount() const
virtual SfxItemSet & GetItemSet()
virtual void BrkCreate(SdrDragStat &rStat) override
Definition: svdotable.cxx:2337
rtl::Reference< SdrTableObjImpl > mpImpl
Definition: svdotable.hxx:281
virtual void EndTextEdit(SdrOutliner &rOutl) override
Definition: svdotable.cxx:1861
constexpr sal_uInt16 SDRATTR_MISC_LAST(SDRATTR_TEXT_CHAINNEXTNAME)
const sal_Int32 last_column_style
Definition: tabledesign.hxx:32
media shape
Definition: svdobjkind.hxx:57
EEControlBits
All geometrical data of an arbitrary object for use in undo/redo.
Definition: svdobj.hxx:174
CellPos getLeftCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:940
SdrObjKind
Definition: svdobjkind.hxx:24
virtual void NbcMove(const Size &rSiz) override
The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and SetLogicRect call the corresponding ...
Definition: svdotable.cxx:1955
constexpr TypedWhichId< SvxFrameDirectionItem > EE_PARA_WRITINGDIR(EE_PARA_START+0)
virtual void SetChanged() override
Definition: svdotable.cxx:2431
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:2082
bool mbInEditMode
Definition: svdotext.hxx:235
bool bSnapRectDirty
Definition: svdobj.hxx:879
Point RightCenter() const
virtual PointerStyle GetCreatePointer() const override
get the cursor/pointer that signals creating this object
Definition: svdotable.cxx:2361
bool IsEmpty() const
tools::Long getHeight() const
TableStyleSettings maTableStyle
Definition: svdotable.cxx:201
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:196
const SdrHdl * GetHdl() const
Definition: svddrag.hxx:101
virtual bool applySpecialDrag(SdrDragStat &rDrag) override
Definition: svdotable.cxx:2223
virtual SdrText * getText(sal_Int32 nIndex) const override
Returns the nth available text.
Definition: svdotable.cxx:1317
virtual const tools::Rectangle & GetLogicRect() const override
Definition: svdotable.cxx:1809
void SetControlWord(EEControlBits nWord)
tools::Long Left() const
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:25
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
virtual const tools::Rectangle & GetSnapRect() const override
Definition: svdotable.cxx:1797
void DragEdge(bool mbHorizontal, int nEdge, sal_Int32 nOffset)
Definition: svdotable.cxx:587
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdotext.cxx:1440
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:1803
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:2072
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2141
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: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:2411
const sdr::table::TableStyleSettings & getTableStyleSettings() const
Definition: svdotable.cxx:1136
bool bClosedObj
Definition: svdobj.hxx:892
CellPos getPreviousCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:998
EEControlBits GetControlWord() const
void SetObjectItem(const SfxPoolItem &rItem)
Definition: svdobj.cxx:1895
Point LeftCenter() const
void DistributeRows(sal_Int32 nFirstRow, sal_Int32 nLastRow, const bool bOptimize, const bool bMinimize)
Definition: svdotable.cxx:2421
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
void getActiveCellPos(sdr::table::CellPos &rPos) const
Definition: svdotable.cxx:1608
virtual EEAnchorMode GetOutlinerViewAnchorMode() const override
Definition: svdotable.cxx:1708
static SdrTableObjImpl * lastLayoutTable
Definition: svdotable.cxx:242
virtual bool HasText() const override
Definition: svdotable.cxx:1404
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:318
CellPos getPreviousRow(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:1067
virtual ~SdrTableObjImpl() override
Definition: svdotable.cxx:270
Point BottomRight() const
const SfxPoolItem & GetObjectItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:1920
virtual void AddToHdlList(SdrHdlList &rHdlList) const override
Definition: svdotable.cxx:2094
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:777
void ResizeRect(tools::Rectangle &rRect, const Point &rRef, const Fraction &rxFact, const Fraction &ryFact)
Definition: svdtrans.cxx:37
Reference< XIndexAccess > mxTableStyle
Definition: svdotable.cxx:202
SdrTableObj & operator=(const SdrTableObj &rObj)
Definition: svdotable.cxx:1763
#define TOOLS_WARN_EXCEPTION(area, stream)
void SetObj(SdrObject *pNewObj)
Definition: svdhdl.cxx:377
void init(sal_Int32 nColumns, sal_Int32 nRows)
Definition: svdotable.cxx:885
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:668
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:1931
void MoveTo(SdrHdlList &rOther)
Definition: svdhdl.cxx:2323
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:730
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:928
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:748
void changeEdge(bool bHorizontal, int nEdge, sal_Int32 nOffset)
Definition: svdotable.cxx:1575
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:1632
virtual bool EndCreate(SdrDragStat &rStat, SdrCreateCmd eCmd) override
Definition: svdotable.cxx:2330
void SetBottom(tools::Long v)
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:2379
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:250
tools::Long Top() const
Abstract DrawObject.
Definition: svdobj.hxx:260
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:1160
std::unique_ptr< TableLayouter > mpLayouter
Definition: svdotable.cxx:199
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:984
virtual SdrTableObj * CloneSdrObject(SdrModel &rTargetModel) const override
Definition: svdotable.cxx:1758
bool operator==(const TableStyleSettings &r) const
Definition: svdotable.cxx:181
bool bTextFrame
Definition: svdotext.hxx:231
css::text::WritingMode GetWritingMode() const
Definition: svdotable.cxx:2037
Paragraph * GetParagraph(sal_Int32 nAbsPos) const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
void setTableStyleSettings(const sdr::table::TableStyleSettings &rStyle)
Definition: svdotable.cxx:1150
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
virtual SdrText * getActiveText() const override
Returns the currently active text.
Definition: svdotable.cxx:1310
const css::uno::Reference< css::container::XIndexAccess > & getTableStyle() const
Definition: svdotable.cxx:1292
const SfxItemSet & GetActiveCellItemSet() const
Definition: svdotable.cxx:1275
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:1911
static CellPos getFirstCell()
Definition: svdotable.cxx:922
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:2062
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:1570
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:1820
void init(SdrTableObj *pTable, sal_Int32 nColumns, sal_Int32 nRows)
Definition: svdotable.cxx:367
virtual bool MovCreate(SdrDragStat &rStat) override
Definition: svdotable.cxx:2317
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdotext.cxx:1448
static tools::Rectangle lastLayoutInputRectangle
Definition: svdotable.cxx:243
virtual bool BegCreate(SdrDragStat &rStat) override
Every object must be able to create itself interactively.
Definition: svdotable.cxx:2306
const sal_Int32 odd_columns_style
Definition: tabledesign.hxx:36
static tools::Rectangle lastLayoutResultRectangle
Definition: svdotable.cxx:244
tools::Rectangle maLogicRect
Definition: svdotable.cxx:150
sal_Int32 GetValidDragOffset(const SdrDragStat &rDrag) const
virtual OUString TakeObjNameSingul() const override
Definition: svdotable.cxx:1735
const sal_Int32 body_style
Definition: tabledesign.hxx:37
virtual OutlinerParaObject * GetOutlinerParaObject() const override
Definition: svdotext.cxx:1362
const sal_Int32 even_rows_style
Definition: tabledesign.hxx:33
virtual void AdjustToMaxRect(const tools::Rectangle &rMaxRect, bool bShrinkOnly=false) override
Definition: svdotable.cxx:1947
virtual void onEditOutlinerStatusEvent(EditStatus *pEditStatus) override
called from the SdrObjEditView during text edit when the status of the edit outliner changes ...
Definition: svdotable.cxx:1415
OUString aName
virtual bool IsVerticalWriting() const override
Definition: svdotable.cxx:2020
CellPos getNextCell(const CellPos &rPos, bool bEdgeTravel) const
Definition: svdotable.cxx:1025
void SetMinAutoPaperSize(const Size &rSz)
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: svdobj.cxx:1707
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: svdotable.cxx:735
tools::Long AdjustWidth(tools::Long n)
virtual void NbcReformatText() override
Definition: svdotable.cxx:2014
void Init(OutlinerMode nOutlinerMode)
void SetOutlinerParaObject(std::unique_ptr< OutlinerParaObject > pTextObject)
Definition: svdobj.cxx:1734
tools::Long Height() const
virtual void RecalcSnapRect() override
Snap is not done on the BoundRect but if possible on logic coordinates (i.e.
Definition: svdotable.cxx:1815
void SetRefDevice(OutputDevice *pRefDev)
virtual bool hasSpecialDrag() const override
The standard transformations (Move,Resize,Rotate,Mirror,Shear) are taken over by the View (TakeXorPol...
Definition: svdotable.cxx:2182
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)
sal_Int32 getColumnCount() const
Definition: svdotable.cxx:1565
static sal_Int32 lastColCount
Definition: svdotable.cxx:249
void setActiveCell(const sdr::table::CellPos &rPos)
Definition: svdotable.cxx:1581
PointerStyle
sal_Int32 getColumnCount() const
Definition: svdotable.cxx:772
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:247
void setHeight(tools::Long nHeight)
EEAnchorMode
tools::Long GetHeight() const
void UpdateCells(tools::Rectangle const &rArea)
Definition: svdotable.cxx:833
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:1335
ScXMLEditAttributeMap::Entry const aEntries[]
void SetTextObj(const SdrTextObj *pObj)
Definition: svdoutl.cxx:40
SdrTableObj(SdrModel &rSdrModel)
Definition: svdotable.cxx:861
virtual bool BckCreate(SdrDragStat &rStat) override
Definition: svdotable.cxx:2342
virtual bool IsAutoGrowHeight() const override
Definition: svdotable.cxx:1394
bool UpdateFields()
virtual SdrObjKind GetObjIdentifier() const override
Definition: svdotable.cxx:1453
std::vector< std::unique_ptr< SdrUndoAction > > maUndos
Definition: svdotable.cxx:203
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:1368
SdrCreateCmd
Definition: svdtypes.hxx:27
virtual void SetVerticalWriting(bool bVertical) override
Definition: svdotable.cxx:2027
virtual void SetChanged()
Definition: svdobj.cxx:929
virtual ~SdrTableObj() override
Definition: svdotable.cxx:901
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:2067
TableStyleSettings & operator=(const TableStyleSettings &rStyle)
Definition: svdotable.cxx:170
virtual OUString TakeObjNamePlural() const override
Definition: svdotable.cxx:1752
static void ImpJustifyRect(tools::Rectangle &rRect)
Definition: svdotext.cxx:374
virtual basegfx::B2DPolyPolygon getSpecialDragPoly(const SdrDragStat &rDrag) const override
Definition: svdotable.cxx:2284
Point TopRight() const
SdrTextVertAdjust
Definition: sdtaitm.hxx:29
void SendUserCall(SdrUserCallType eUserCall, const tools::Rectangle &rBoundRect) const
Definition: svdobj.cxx:2655
virtual bool AdjustTextFrameWidthAndHeight() override
Definition: svdotable.cxx:1975
const sdr::table::CellRef & getActiveCell() const
The active table has the focus or is currently edited.
Definition: svdotable.cxx:1546
const TableLayouter & getTableLayouter() const
Definition: svdotable.cxx:1388
bool GetUpdateMode() const
const sal_Int32 last_row_style
Definition: tabledesign.hxx:30
void AddHdl(std::unique_ptr< SdrHdl > pHdl)
Definition: svdhdl.cxx:2289
void setHeight(tools::Long n)
Point TopCenter() const
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override
Definition: svdotable.cxx:2455
SdrHdlKind GetKind() const
Definition: svdhdl.hxx:194
void getCellBounds(const sdr::table::CellPos &rPos,::tools::Rectangle &rCellRect)
Definition: svdotable.cxx:1614
bool createTableEdgesJson(boost::property_tree::ptree &rJsonRoot)
Definition: svdotable.cxx:2467
const sal_Int32 odd_rows_style
Definition: tabledesign.hxx:34
const Size & GetPaperSize() const