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