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