LibreOffice Module sc (master)  1
docuno.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 <config_feature_opencl.h>
21 
22 #include <boost/property_tree/json_parser.hpp>
23 
24 #include <scitems.hxx>
25 #include <comphelper/sequence.hxx>
26 #include <editeng/editview.hxx>
27 #include <editeng/outliner.hxx>
28 #include <o3tl/any.hxx>
29 #include <o3tl/safeint.hxx>
30 #include <svx/fmview.hxx>
31 #include <svx/svditer.hxx>
32 #include <svx/svdpage.hxx>
33 #include <svx/svxids.hrc>
34 #include <svx/unoshape.hxx>
35 
36 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
38 #include <officecfg/Office/Common.hxx>
39 #include <officecfg/Office/Calc.hxx>
40 #include <svl/numuno.hxx>
41 #include <svl/hint.hxx>
43 #include <sfx2/bindings.hxx>
44 #include <sfx2/dispatch.hxx>
45 #include <sfx2/viewfrm.hxx>
46 #include <svx/unopage.hxx>
47 #include <vcl/pdfextoutdevdata.hxx>
48 #include <vcl/print.hxx>
49 #include <vcl/svapp.hxx>
50 #include <tools/json_writer.hxx>
51 #include <tools/multisel.hxx>
52 #include <tools/UnitConversion.hxx>
54 #include <unotools/saveopt.hxx>
55 
56 #include <float.h>
57 
58 #include <com/sun/star/beans/PropertyAttribute.hpp>
59 #include <com/sun/star/util/Date.hpp>
60 #include <com/sun/star/sheet/XNamedRanges.hpp>
61 #include <com/sun/star/sheet/XLabelRanges.hpp>
62 #include <com/sun/star/sheet/XSelectedSheetsSupplier.hpp>
63 #include <com/sun/star/sheet/XUnnamedDatabaseRanges.hpp>
64 #include <com/sun/star/i18n/XForbiddenCharacters.hpp>
65 #include <com/sun/star/script/XLibraryContainer.hpp>
66 #include <com/sun/star/lang/XInitialization.hpp>
67 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
68 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
69 #include <com/sun/star/document/IndexedPropertyValues.hpp>
70 #include <com/sun/star/script/XInvocation.hpp>
71 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
72 #include <com/sun/star/beans/XFastPropertySet.hpp>
73 #include <comphelper/lok.hxx>
77 #include <comphelper/string.hxx>
79 #if HAVE_FEATURE_OPENCL
80 #include <opencl/platforminfo.hxx>
81 #endif
82 #include <sfx2/lokhelper.hxx>
83 #include <sfx2/lokcharthelper.hxx>
84 
85 #include <cellsuno.hxx>
86 #include <columnspanset.hxx>
87 #include <convuno.hxx>
88 #include <datauno.hxx>
89 #include <docfunc.hxx>
90 #include <docoptio.hxx>
91 #include <docsh.hxx>
92 #include <docuno.hxx>
93 #include <drwlayer.hxx>
94 #include <forbiuno.hxx>
95 #include <formulagroup.hxx>
96 #include <gridwin.hxx>
97 #include <hints.hxx>
98 #include <inputhdl.hxx>
99 #include <inputopt.hxx>
100 #include <interpre.hxx>
101 #include <linkuno.hxx>
102 #include <markdata.hxx>
103 #include <miscuno.hxx>
104 #include <nameuno.hxx>
105 #include <notesuno.hxx>
106 #include <optuno.hxx>
107 #include <pfuncache.hxx>
108 #include <postit.hxx>
109 #include <printfun.hxx>
110 #include <rangeutl.hxx>
111 #include <scmod.hxx>
112 #include <scresid.hxx>
113 #include <servuno.hxx>
114 #include <shapeuno.hxx>
115 #include <sheetevents.hxx>
116 #include <styleuno.hxx>
117 #include <tabvwsh.hxx>
118 #include <targuno.hxx>
119 #include <unonames.hxx>
121 #include <editsh.hxx>
122 #include <drawsh.hxx>
123 #include <drtxtob.hxx>
124 #include <transobj.hxx>
125 #include <chgtrack.hxx>
126 #include <table.hxx>
127 #include <appoptio.hxx>
128 #include <formulaopt.hxx>
129 
130 #include <strings.hrc>
131 
132 using namespace com::sun::star;
133 
134 // #i111553# provides the name of the VBA constant for this document type (e.g. 'ThisExcelDoc' for Calc)
135 #define SC_UNO_VBAGLOBNAME "VBAGlobalConstantName"
136 
137 // no Which-ID here, map only for PropertySetInfo
138 
141 {
142  static const SfxItemPropertyMapEntry aDocOptPropertyMap_Impl[] =
143  {
144  {OUString(SC_UNO_APPLYFMDES), 0, cppu::UnoType<bool>::get(), 0, 0},
146  {OUString(SC_UNO_AUTOCONTFOC), 0, cppu::UnoType<bool>::get(), 0, 0},
147  {OUString(SC_UNO_BASICLIBRARIES), 0, cppu::UnoType<script::XLibraryContainer>::get(), beans::PropertyAttribute::READONLY, 0},
148  {OUString(SC_UNO_DIALOGLIBRARIES), 0, cppu::UnoType<script::XLibraryContainer>::get(), beans::PropertyAttribute::READONLY, 0},
149  {OUString(SC_UNO_VBAGLOBNAME), 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0},
151  {OUString(SC_UNONAME_CLOCAL), 0, cppu::UnoType<lang::Locale>::get(), 0, 0},
152  {OUString(SC_UNO_CJK_CLOCAL), 0, cppu::UnoType<lang::Locale>::get(), 0, 0},
153  {OUString(SC_UNO_CTL_CLOCAL), 0, cppu::UnoType<lang::Locale>::get(), 0, 0},
158  {OUString(SC_UNO_FORBIDDEN), 0, cppu::UnoType<i18n::XForbiddenCharacters>::get(), beans::PropertyAttribute::READONLY, 0},
159  {OUString(SC_UNO_HASDRAWPAGES), 0, cppu::UnoType<bool>::get(), beans::PropertyAttribute::READONLY, 0},
175  {OUString(SC_UNO_RUNTIMEUID), 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0},
176  {OUString(SC_UNO_HASVALIDSIGNATURES), 0, cppu::UnoType<bool>::get(), beans::PropertyAttribute::READONLY, 0},
177  {OUString(SC_UNO_ISLOADED), 0, cppu::UnoType<bool>::get(), 0, 0},
178  {OUString(SC_UNO_ISUNDOENABLED), 0, cppu::UnoType<bool>::get(), 0, 0},
179  {OUString(SC_UNO_RECORDCHANGES), 0, cppu::UnoType<bool>::get(), 0, 0},
180  {OUString(SC_UNO_ISRECORDCHANGESPROTECTED),0, cppu::UnoType<bool>::get(), beans::PropertyAttribute::READONLY, 0},
184  {OUString(SC_UNO_REFERENCEDEVICE), 0, cppu::UnoType<awt::XDevice>::get(), beans::PropertyAttribute::READONLY, 0},
185  {OUString("BuildId"), 0, ::cppu::UnoType<OUString>::get(), 0, 0},
186  {OUString(SC_UNO_CODENAME), 0, cppu::UnoType<OUString>::get(), 0, 0},
188  { OUString(), 0, css::uno::Type(), 0, 0 }
189  };
190  return aDocOptPropertyMap_Impl;
191 }
192 
194 
196 {
197  static const SfxItemPropertyMapEntry aColumnsPropertyMap_Impl[] =
198  {
199  {OUString(SC_UNONAME_MANPAGE), 0, cppu::UnoType<bool>::get(), 0, 0 },
200  {OUString(SC_UNONAME_NEWPAGE), 0, cppu::UnoType<bool>::get(), 0, 0 },
201  {OUString(SC_UNONAME_CELLVIS), 0, cppu::UnoType<bool>::get(), 0, 0 },
202  {OUString(SC_UNONAME_OWIDTH), 0, cppu::UnoType<bool>::get(), 0, 0 },
203  {OUString(SC_UNONAME_CELLWID), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
204  { OUString(), 0, css::uno::Type(), 0, 0 }
205  };
206  return aColumnsPropertyMap_Impl;
207 }
208 
210 {
211  static const SfxItemPropertyMapEntry aRowsPropertyMap_Impl[] =
212  {
213  {OUString(SC_UNONAME_CELLHGT), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
214  {OUString(SC_UNONAME_CELLFILT), 0, cppu::UnoType<bool>::get(), 0, 0 },
215  {OUString(SC_UNONAME_OHEIGHT), 0, cppu::UnoType<bool>::get(), 0, 0 },
216  {OUString(SC_UNONAME_MANPAGE), 0, cppu::UnoType<bool>::get(), 0, 0 },
217  {OUString(SC_UNONAME_NEWPAGE), 0, cppu::UnoType<bool>::get(), 0, 0 },
218  {OUString(SC_UNONAME_CELLVIS), 0, cppu::UnoType<bool>::get(), 0, 0 },
221  // not sorted, not used with SfxItemPropertyMapEntry::GetByName
222  { OUString(), 0, css::uno::Type(), 0, 0 }
223  };
224  return aRowsPropertyMap_Impl;
225 }
226 
227 using sc::HMMToTwips;
228 using sc::TwipsToHMM;
229 
230 #define SCMODELOBJ_SERVICE "com.sun.star.sheet.SpreadsheetDocument"
231 #define SCDOCSETTINGS_SERVICE "com.sun.star.sheet.SpreadsheetDocumentSettings"
232 #define SCDOC_SERVICE "com.sun.star.document.OfficeDocument"
233 
234 SC_SIMPLE_SERVICE_INFO( ScAnnotationsObj, "ScAnnotationsObj", "com.sun.star.sheet.CellAnnotations" )
235 SC_SIMPLE_SERVICE_INFO( ScDrawPagesObj, "ScDrawPagesObj", "com.sun.star.drawing.DrawPages" )
236 SC_SIMPLE_SERVICE_INFO( ScScenariosObj, "ScScenariosObj", "com.sun.star.sheet.Scenarios" )
237 SC_SIMPLE_SERVICE_INFO( ScSpreadsheetSettingsObj, "ScSpreadsheetSettingsObj", "com.sun.star.sheet.SpreadsheetDocumentSettings" )
238 SC_SIMPLE_SERVICE_INFO( ScTableColumnsObj, "ScTableColumnsObj", "com.sun.star.table.TableColumns" )
239 SC_SIMPLE_SERVICE_INFO( ScTableRowsObj, "ScTableRowsObj", "com.sun.star.table.TableRows" )
240 SC_SIMPLE_SERVICE_INFO( ScTableSheetsObj, "ScTableSheetsObj", "com.sun.star.sheet.Spreadsheets" )
241 
242 class ScPrintUIOptions : public vcl::PrinterOptionsHelper
243 {
244 public:
246  void SetDefaults();
247 };
248 
250 {
251  const ScPrintOptions& rPrintOpt = SC_MOD()->GetPrintOptions();
252  sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
253  bool bSuppress = rPrintOpt.GetSkipEmpty();
254 
255  sal_Int32 nNumProps= 10, nIdx = 0;
256 
257  m_aUIProperties.resize(nNumProps);
258 
259  // load the writer PrinterOptions into the custom tab
260  m_aUIProperties[nIdx].Name = "OptionsUIFile";
261  m_aUIProperties[nIdx++].Value <<= OUString("modules/scalc/ui/printeroptions.ui");
262 
263  // create Section for spreadsheet (results in an extra tab page in dialog)
264  SvtModuleOptions aOpt;
265  OUString aAppGroupname( ScResId( SCSTR_PRINTOPT_PRODNAME ) );
266  aAppGroupname = aAppGroupname.replaceFirst( "%s", aOpt.GetModuleName( SvtModuleOptions::EModule::CALC ) );
267  m_aUIProperties[nIdx++].Value = setGroupControlOpt("tabcontrol-page2", aAppGroupname, OUString());
268 
269  // show subgroup for pages
270  m_aUIProperties[nIdx++].Value = setSubgroupControlOpt("pages", ScResId( SCSTR_PRINTOPT_PAGES ), OUString());
271 
272  // create a bool option for empty pages
273  m_aUIProperties[nIdx++].Value = setBoolControlOpt("suppressemptypages", ScResId( SCSTR_PRINTOPT_SUPPRESSEMPTY ),
274  ".HelpID:vcl:PrintDialog:IsSuppressEmptyPages:CheckBox",
275  "IsSuppressEmptyPages",
276  bSuppress);
277  // show Subgroup for print content
279  aPrintRangeOpt.maGroupHint = "PrintRange";
280  m_aUIProperties[nIdx++].Value = setSubgroupControlOpt("printrange", ScResId( SCSTR_PRINTOPT_PAGES ),
281  OUString(),
282  aPrintRangeOpt);
283 
284  // create a choice for the content to create
285  uno::Sequence< OUString > aChoices{
286  ScResId( SCSTR_PRINTOPT_ALLSHEETS ),
287  ScResId( SCSTR_PRINTOPT_SELECTEDSHEETS ),
288  ScResId( SCSTR_PRINTOPT_SELECTEDCELLS )};
289  uno::Sequence< OUString > aHelpIds{
290  ".HelpID:vcl:PrintDialog:PrintContent:ListBox"};
291  m_aUIProperties[nIdx++].Value = setChoiceListControlOpt( "printextrabox", OUString(),
292  aHelpIds, "PrintContent",
293  aChoices, nContent );
294 
295  // show Subgroup for print range
296  aPrintRangeOpt.mbInternalOnly = true;
297  m_aUIProperties[nIdx++].Value = setSubgroupControlOpt("fromwhich", ScResId( SCSTR_PRINTOPT_FROMWHICH ),
298  OUString(),
299  aPrintRangeOpt);
300 
301  // create a choice for the range to print
302  OUString aPrintRangeName( "PrintRange" );
303  aChoices.realloc( 2 );
304  aHelpIds.realloc( 2 );
305  uno::Sequence< OUString > aWidgetIds( 2 );
306  aChoices[0] = ScResId( SCSTR_PRINTOPT_PRINTALLPAGES );
307  aHelpIds[0] = ".HelpID:vcl:PrintDialog:PrintRange:RadioButton:0";
308  aWidgetIds[0] = "rbAllPages";
309  aChoices[1] = ScResId( SCSTR_PRINTOPT_PRINTPAGES );
310  aHelpIds[1] = ".HelpID:vcl:PrintDialog:PrintRange:RadioButton:1";
311  aWidgetIds[1] = "rbRangePages";
312  m_aUIProperties[nIdx++].Value = setChoiceRadiosControlOpt(aWidgetIds, OUString(),
313  aHelpIds,
314  aPrintRangeName,
315  aChoices,
316  0 );
317 
318  // create an Edit dependent on "Pages" selected
319  vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, true );
320  m_aUIProperties[nIdx++].Value = setEditControlOpt("pagerange", OUString(),
321  ".HelpID:vcl:PrintDialog:PageRange:Edit",
322  "PageRange", OUString(), aPageRangeOpt);
323 
324  vcl::PrinterOptionsHelper::UIControlOptions aEvenOddOpt(aPrintRangeName, 0, true);
325  m_aUIProperties[ nIdx++ ].Value = setChoiceListControlOpt("evenoddbox",
326  OUString(),
327  uno::Sequence<OUString>(),
328  "EvenOdd",
329  uno::Sequence<OUString>(),
330  0,
331  uno::Sequence< sal_Bool >(),
332  aEvenOddOpt);
333 
334  assert(nIdx == nNumProps);
335 }
336 
338 {
339  // re-initialize the default values from print options
340 
341  const ScPrintOptions& rPrintOpt = SC_MOD()->GetPrintOptions();
342  sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
343  bool bSuppress = rPrintOpt.GetSkipEmpty();
344 
345  for (beans::PropertyValue & rPropValue : m_aUIProperties)
346  {
347  uno::Sequence<beans::PropertyValue> aUIProp;
348  if ( rPropValue.Value >>= aUIProp )
349  {
350  for (auto& rProp : aUIProp)
351  {
352  OUString aName = rProp.Name;
353  if ( aName == "Property" )
354  {
355  beans::PropertyValue aPropertyValue;
356  if ( rProp.Value >>= aPropertyValue )
357  {
358  if ( aPropertyValue.Name == "PrintContent" )
359  {
360  aPropertyValue.Value <<= nContent;
361  rProp.Value <<= aPropertyValue;
362  }
363  else if ( aPropertyValue.Name == "IsSuppressEmptyPages" )
364  {
365  aPropertyValue.Value <<= bSuppress;
366  rProp.Value <<= aPropertyValue;
367  }
368  }
369  }
370  }
371  rPropValue.Value <<= aUIProp;
372  }
373  }
374 }
375 
377 {
378  if (pDocSh)
379  pDocSh->SetBaseModel( new ScModelObj(pDocSh) );
380 }
381 
383 {
384  ScDocument& rDoc(pDocShell->GetDocument());
385 
386  if(!rDoc.GetDrawLayer())
387  {
388  rDoc.InitDrawLayer();
389  }
390 
391  return *rDoc.GetDrawLayer(); // TTTT should be reference
392 }
393 
395  SfxBaseModel( pDocSh ),
396  aPropSet( lcl_GetDocOptPropertyMap() ),
397  pDocShell( pDocSh ),
398  maChangesListeners( m_aMutex )
399 {
400  // pDocShell may be NULL if this is the base of a ScDocOptionsObj
401  if ( pDocShell )
402  {
403  pDocShell->GetDocument().AddUnoObject(*this); // SfxModel is derived from SfxListener
404  }
405 }
406 
408 {
409  SolarMutexGuard g;
410 
411  if (pDocShell)
413 
414  if (xNumberAgg.is())
415  xNumberAgg->setDelegator(uno::Reference<uno::XInterface>());
416 
417  pPrintFuncCache.reset();
418  pPrinterOptions.reset();
419 }
420 
421 uno::Reference< uno::XAggregation> const & ScModelObj::GetFormatter()
422 {
423  // pDocShell may be NULL if this is the base of a ScDocOptionsObj
424  if ( !xNumberAgg.is() && pDocShell )
425  {
426  // setDelegator changes RefCount, so we'd better hold the reference ourselves
427  // (directly in m_refCount, so we don't delete ourselves with release())
428  osl_atomic_increment( &m_refCount );
429  // we need a reference to SvNumberFormatsSupplierObj during queryInterface,
430  // otherwise it'll be deleted
431  uno::Reference<util::XNumberFormatsSupplier> xFormatter(
433  {
434  xNumberAgg.set(uno::Reference<uno::XAggregation>( xFormatter, uno::UNO_QUERY ));
435  // extra block to force deletion of the temporary before setDelegator
436  }
437 
438  // during setDelegator no additional reference should exist
439  xFormatter = nullptr;
440 
441  if (xNumberAgg.is())
442  xNumberAgg->setDelegator( static_cast<cppu::OWeakObject*>(this) );
443  osl_atomic_decrement( &m_refCount );
444  } // if ( !xNumberAgg.is() )
445  return xNumberAgg;
446 }
447 
449 {
450  if (pDocShell)
451  return &pDocShell->GetDocument();
452  return nullptr;
453 }
454 
456 {
457  return pDocShell;
458 }
459 
461 {
462  if (pDocShell)
464 }
465 
467 {
468  if (pDocShell)
470 }
471 
473 {
474  if (pDocShell)
475  pDocShell->AfterXMLLoading(true);
476 }
477 
479 {
480  if (pDocShell)
481  return pDocShell->GetSheetSaveData();
482  return nullptr;
483 }
484 
486 {
487  if (pDocShell)
488  return pDocShell->GetFormatSaveData();
489  return nullptr;
490 }
491 
492 void ScModelObj::RepaintRange( const ScRange& rRange )
493 {
494  if (pDocShell)
496 }
497 
499 {
500  if (pDocShell)
502 }
503 
505  const Fraction& rZoomY,
506  const SCTAB nTab,
507  const ViewShellDocId& rDocId)
508 {
509  constexpr size_t nMaxIter = 5;
510  size_t nIter = 0;
511  for (SfxViewShell* pViewShell = SfxViewShell::GetFirst();
512  pViewShell && nIter < nMaxIter;
513  (pViewShell = SfxViewShell::GetNext(*pViewShell)), ++nIter)
514  {
515  if (pViewShell->GetDocId() != rDocId)
516  continue;
517 
518  ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
519  if (!pTabViewShell)
520  continue;
521 
522  ScViewData& rData = pTabViewShell->GetViewData();
523  if (rData.GetTabNo() == nTab && rData.GetZoomX() == rZoomX && rData.GetZoomY() == rZoomY)
524  return &rData;
525  }
526 
527  return nullptr;
528 }
529 
531  int nOutputWidth, int nOutputHeight,
532  int nTilePosX, int nTilePosY,
533  long nTileWidth, long nTileHeight )
534 {
535  ScTabViewShell* pViewShell = pDocShell->GetBestViewShell(false);
536 
537  // FIXME: Can this happen? What should we do?
538  if (!pViewShell)
539  return;
540 
541  ScViewData* pActiveViewData = &pViewShell->GetViewData();
542  Fraction aFracX(long(nOutputWidth * TWIPS_PER_PIXEL), nTileWidth);
543  Fraction aFracY(long(nOutputHeight * TWIPS_PER_PIXEL), nTileHeight);
544 
545  // Try to find a view that matches the tile-zoom requested by iterating over
546  // first few shells. This is to avoid switching of zooms in ScGridWindow::PaintTile
547  // and hence avoid grid-offset recomputation on all shapes which is not cheap.
548  ScViewData* pViewData = lcl_getViewMatchingDocZoomTab(aFracX, aFracY,
549  pActiveViewData->GetTabNo(), pViewShell->GetDocId());
550  if (!pViewData)
551  pViewData = pActiveViewData;
552 
553  ScGridWindow* pGridWindow = pViewData->GetActiveWin();
554 
555  // update the size of the area we are painting
556  // FIXME we want to use only the minimal necessary size, like the
557  // following; but for the moment there is too many problems with that and
558  // interaction with editeng used for the cell editing
559  //Size aTileSize(nOutputWidth, nOutputHeight);
560  //if (pGridWindow->GetOutputSizePixel() != aTileSize)
561  // pGridWindow->SetOutputSizePixel(Size(nOutputWidth, nOutputHeight));
562  // so instead for now, set the viewport size to document size
563  Size aDocSize = getDocumentSize();
564  pGridWindow->SetOutputSizePixel(Size(aDocSize.Width() * pViewData->GetPPTX(), aDocSize.Height() * pViewData->GetPPTY()));
565 
566  pGridWindow->PaintTile( rDevice, nOutputWidth, nOutputHeight,
567  nTilePosX, nTilePosY, nTileWidth, nTileHeight );
568 
569  LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
570  nTilePosX, nTilePosY, nTileWidth, nTileHeight);
571 }
572 
573 void ScModelObj::setPart( int nPart )
574 {
575  ScViewData* pViewData = ScDocShell::GetViewData();
576  ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() );
577 
578  if (pTabView)
579  pTabView->SelectTabPage(nPart + 1);
580 }
581 
583 {
584  ScDocument& rDoc = pDocShell->GetDocument();
585  return rDoc.GetTableCount();
586 }
587 
589 {
590  ScViewData* pViewData = ScDocShell::GetViewData();
591  return pViewData ? pViewData->GetViewShell()->getPart() : 0;
592 }
593 
594 OUString ScModelObj::getPartInfo( int nPart )
595 {
596  ScViewData* pViewData = ScDocShell::GetViewData();
597  const bool bIsVisible = pViewData->GetDocument()->IsVisible(nPart);
598  //FIXME: Implement IsSelected().
599  const bool bIsSelected = false; //pViewData->GetDocument()->IsSelected(nPart);
600 
601  OUString aPartInfo = "{ \"visible\": \"" +
602  OUString::number(static_cast<unsigned int>(bIsVisible)) +
603  "\", \"selected\": \"" +
604  OUString::number(static_cast<unsigned int>(bIsSelected)) +
605  "\" }";
606  return aPartInfo;
607 }
608 
609 OUString ScModelObj::getPartName( int nPart )
610 {
611  OUString sTabName;
612  ScViewData* pViewData = ScDocShell::GetViewData();
613  pViewData->GetDocument()->GetName(nPart, sTabName);
614  return sTabName;
615 }
616 
617 OUString ScModelObj::getPartHash( int nPart )
618 {
619  sal_Int64 nHashCode;
620  ScViewData* pViewData = ScDocShell::GetViewData();
621  return (pViewData->GetDocument()->GetHashCode(nPart, nHashCode) ? OUString::number(nHashCode) : OUString());
622 }
623 
625 {
626  SolarMutexGuard aGuard;
627 
628  ScTabViewShell* pViewShell = pDocShell->GetBestViewShell(false);
629 
630  // FIXME: Can this happen? What should we do?
631  if (!pViewShell)
632  return VclPtr<vcl::Window>();
633 
634  ScViewData* pViewData = &pViewShell->GetViewData();
635 
636  VclPtr<vcl::Window> pWindow;
637  if (pViewData)
638  {
639  pWindow = pViewData->GetActiveWin();
640 
641  LokChartHelper aChartHelper(pViewData->GetViewShell());
642  vcl::Window* pChartWindow = aChartHelper.GetWindow();
643  if (pChartWindow)
644  pWindow = pChartWindow;
645  }
646 
647  return pWindow;
648 }
649 
651 {
652  Size aSize(10, 10); // minimum size
653 
654  ScViewData* pViewData = ScDocShell::GetViewData();
655  if (!pViewData)
656  return aSize;
657 
658  SCTAB nTab = pViewData->GetTabNo();
659  SCCOL nEndCol = 0;
660  SCROW nEndRow = 0;
661  const ScDocument& rDoc = pDocShell->GetDocument();
662 
663  rDoc.GetTiledRenderingArea(nTab, nEndCol, nEndRow);
664 
665  const ScDocument* pThisDoc = &rDoc;
666  const double fPPTX = pViewData->GetPPTX();
667  const double fPPTY = pViewData->GetPPTY();
668 
669  auto GetColWidthPx = [pThisDoc, fPPTX, nTab](SCCOL nCol) {
670  const sal_uInt16 nSize = pThisDoc->GetColWidth(nCol, nTab);
671  return ScViewData::ToPixel(nSize, fPPTX);
672  };
673 
674  long nDocWidthPixel = pViewData->GetLOKWidthHelper().computePosition(nEndCol, GetColWidthPx);
675  long nDocHeightPixel = pThisDoc->GetScaledRowHeight(0, nEndRow, nTab, fPPTY);
676 
677  if (nDocWidthPixel > 0 && nDocHeightPixel > 0)
678  {
679  // convert to twips
680  aSize.setWidth(nDocWidthPixel / fPPTX);
681  aSize.setHeight(nDocHeightPixel / fPPTY);
682  }
683  else
684  {
685  // convert to twips
686  aSize.setWidth(rDoc.GetColWidth(0, nEndCol, nTab));
687  aSize.setHeight(rDoc.GetRowHeight(0, nEndRow, nTab));
688  }
689 
690  return aSize;
691 }
692 
693 
694 void ScModelObj::postKeyEvent(int nType, int nCharCode, int nKeyCode)
695 {
696  SolarMutexGuard aGuard;
697  SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode);
698 }
699 
700 void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
701 {
702  SolarMutexGuard aGuard;
703 
704  ScTabViewShell* pViewShell = pDocShell->GetBestViewShell(false);
705 
706  // FIXME: Can this happen? What should we do?
707  if (!pViewShell)
708  return;
709 
710  ScViewData* pViewData = &pViewShell->GetViewData();
711 
712  ScGridWindow* pGridWindow = pViewData->GetActiveWin();
713 
714  if (!pGridWindow)
715  return;
716 
717  // check if user hit a chart which is being edited by him
718  ScTabViewShell * pTabViewShell = pViewData->GetViewShell();
719  LokChartHelper aChartHelper(pTabViewShell);
720  if (aChartHelper.postMouseEvent(nType, nX, nY,
721  nCount, nButtons, nModifier,
722  pViewData->GetPPTX(), pViewData->GetPPTY()))
723  return;
724 
725  // check if the user hit a chart which is being edited by someone else
726  // and, if so, skip current mouse event
727  if (nType != LOK_MOUSEEVENT_MOUSEMOVE)
728  {
729  if (LokChartHelper::HitAny(Point(nX, nY)))
730  return;
731  }
732 
733  // Calc operates in pixels...
734  const Point aPos(nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY());
735 
736  LokMouseEventData aMouseEventData(nType, aPos, nCount, MouseEventModifiers::SIMPLECLICK,
737  nButtons, nModifier);
738  aMouseEventData.maLogicPosition = Point(convertTwipToMm100(nX), convertTwipToMm100(nY));
739  SfxLokHelper::postMouseEventAsync(pGridWindow, aMouseEventData);
740 }
741 
742 void ScModelObj::setTextSelection(int nType, int nX, int nY)
743 {
744  SolarMutexGuard aGuard;
745  ScViewData* pViewData = ScDocShell::GetViewData();
746  ScTabViewShell* pViewShell = pViewData->GetViewShell();
747 
748  LokChartHelper aChartHelper(pViewShell);
749  if (aChartHelper.setTextSelection(nType, nX, nY))
750  return;
751 
752  ScInputHandler* pInputHandler = SC_MOD()->GetInputHdl(pViewShell);
753  ScDrawView* pDrawView = pViewData->GetScDrawView();
754 
755  bool bHandled = false;
756 
757  if (pInputHandler && pInputHandler->IsInputMode())
758  {
759  // forwarding to editeng - we are editing the cell content
760  EditView* pTableView = pInputHandler->GetTableView();
761  assert(pTableView);
762 
764 
765  if (pTableView->GetOutputArea().IsInside(aPoint))
766  {
767  switch (nType)
768  {
769  case LOK_SETTEXTSELECTION_START:
770  pTableView->SetCursorLogicPosition(aPoint, /*bPoint=*/false, /*bClearMark=*/false);
771  break;
772  case LOK_SETTEXTSELECTION_END:
773  pTableView->SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/false);
774  break;
775  case LOK_SETTEXTSELECTION_RESET:
776  pTableView->SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/true);
777  break;
778  default:
779  assert(false);
780  break;
781  }
782  bHandled = true;
783  }
784  }
785  else if (pDrawView && pDrawView->IsTextEdit())
786  {
787  // forwarding to editeng - we are editing the text in shape
788  OutlinerView* pOutlinerView = pDrawView->GetTextEditOutlinerView();
789  EditView& rEditView = pOutlinerView->GetEditView();
790 
792  switch (nType)
793  {
794  case LOK_SETTEXTSELECTION_START:
795  rEditView.SetCursorLogicPosition(aPoint, /*bPoint=*/false, /*bClearMark=*/false);
796  break;
797  case LOK_SETTEXTSELECTION_END:
798  rEditView.SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/false);
799  break;
800  case LOK_SETTEXTSELECTION_RESET:
801  rEditView.SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/true);
802  break;
803  default:
804  assert(false);
805  break;
806  }
807  bHandled = true;
808  }
809 
810  if (!bHandled)
811  {
812  // just update the cell selection
813  ScGridWindow* pGridWindow = pViewData->GetActiveWin();
814  if (!pGridWindow)
815  return;
816 
817  // move the cell selection handles
818  pGridWindow->SetCellSelectionPixel(nType, nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY());
819  }
820 }
821 
822 uno::Reference<datatransfer::XTransferable> ScModelObj::getSelection()
823 {
824  SolarMutexGuard aGuard;
825 
826  TransferableDataHelper aDataHelper;
827  ScViewData* pViewData = ScDocShell::GetViewData();
828  uno::Reference<datatransfer::XTransferable> xTransferable;
829 
830  if ( ScEditShell * pShell = dynamic_cast<ScEditShell*>( pViewData->GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) ) )
831  xTransferable = pShell->GetEditView()->GetTransferable();
832  else if ( nullptr != dynamic_cast<ScDrawTextObjectBar*>( pViewData->GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) ))
833  {
834  ScDrawView* pView = pViewData->GetScDrawView();
835  OutlinerView* pOutView = pView->GetTextEditOutlinerView();
836  if (pOutView)
837  xTransferable = pOutView->GetEditView().GetTransferable();
838  }
839  else if ( ScDrawShell * pDrawShell = dynamic_cast<ScDrawShell*>( pViewData->GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) ) )
840  xTransferable = pDrawShell->GetDrawView()->CopyToTransferable();
841  else
842  {
843  ScTransferObj* pObj = pViewData->GetViewShell()->CopyToTransferable();
844  xTransferable.set( pObj );
845  }
846 
847  if (!xTransferable.is())
848  xTransferable.set( aDataHelper.GetTransferable() );
849 
850  return xTransferable;
851 }
852 
853 void ScModelObj::setGraphicSelection(int nType, int nX, int nY)
854 {
855  SolarMutexGuard aGuard;
856 
857  ScTabViewShell* pViewShell = pDocShell->GetBestViewShell(false);
858 
859  // FIXME: Can this happen? What should we do?
860  if (!pViewShell)
861  return;
862 
863  ScViewData* pViewData = &pViewShell->GetViewData();
864 
865  ScGridWindow* pGridWindow = pViewData->GetActiveWin();
866 
867  double fPPTX = pViewData->GetPPTX();
868  double fPPTY = pViewData->GetPPTY();
869 
870  pViewShell = pViewData->GetViewShell();
871  LokChartHelper aChartHelper(pViewShell);
872  if (aChartHelper.setGraphicSelection(nType, nX, nY, fPPTX, fPPTY))
873  return;
874 
875  int nPixelX = nX * fPPTX;
876  int nPixelY = nY * fPPTY;
877 
878  switch (nType)
879  {
880  case LOK_SETGRAPHICSELECTION_START:
881  {
882  MouseEvent aClickEvent(Point(nPixelX, nPixelY), 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
883  pGridWindow->MouseButtonDown(aClickEvent);
884  MouseEvent aMoveEvent(Point(nPixelX, nPixelY), 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT);
885  pGridWindow->MouseMove(aMoveEvent);
886  }
887  break;
888  case LOK_SETGRAPHICSELECTION_END:
889  {
890  MouseEvent aMoveEvent(Point(nPixelX, nPixelY), 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT);
891  pGridWindow->MouseMove(aMoveEvent);
892  MouseEvent aClickEvent(Point(nPixelX, nPixelY), 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
893  pGridWindow->MouseButtonUp(aClickEvent);
894  }
895  break;
896  default:
897  assert(false);
898  break;
899  }
900 }
901 
903 {
904  SolarMutexGuard aGuard;
905 
906  ScViewData* pViewData = ScDocShell::GetViewData();
907  ScTabViewShell* pViewShell = pViewData->GetViewShell();
908 
909  // deselect the shapes & texts
910  ScDrawView* pDrawView = pViewShell->GetScDrawView();
911  if (pDrawView)
912  {
913  pDrawView->ScEndTextEdit();
914  pDrawView->UnmarkAll();
915  }
916  else
917  pViewShell->Unmark();
918 
919  // and hide the cell and text selection
920  pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, "");
921  SfxLokHelper::notifyOtherViews(pViewShell, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", "");
922 }
923 
924 void ScModelObj::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard)
925 {
926  SolarMutexGuard aGuard;
927 
928  ScViewData* pViewData = ScDocShell::GetViewData();
929  if (!pViewData)
930  return;
931 
932  pViewData->GetActiveWin()->SetClipboard(xClipboard);
933 }
934 
936 {
937  SolarMutexGuard aGuard;
938 
939  ScViewData* pViewData = ScDocShell::GetViewData();
940  if (!pViewData)
941  return false;
942 
943 
945  return EditEngine::HasValidData(aDataHelper.GetTransferable());
946 }
947 
948 void ScModelObj::setClientZoom(int nTilePixelWidth_, int nTilePixelHeight_, int nTileTwipWidth_, int nTileTwipHeight_)
949 {
950  ScViewData* pViewData = ScDocShell::GetViewData();
951 
952  if (!pViewData)
953  return;
954 
955  const Fraction newZoomX(nTilePixelWidth_ * TWIPS_PER_PIXEL, nTileTwipWidth_);
956  const Fraction newZoomY(nTilePixelHeight_ * TWIPS_PER_PIXEL, nTileTwipHeight_);
957 
958  if (pViewData->GetZoomX() == newZoomX && pViewData->GetZoomY() == newZoomY)
959  return;
960 
961  pViewData->SetZoom(newZoomX, newZoomY, true);
962 
963  // refresh our view's take on other view's cursors & selections
964  pViewData->GetActiveWin()->updateKitOtherCursors();
965  pViewData->GetActiveWin()->updateOtherKitSelections();
966 
967  if (ScDrawView* pDrawView = pViewData->GetScDrawView())
968  pDrawView->resetGridOffsetsForAllSdrPageViews();
969 }
970 
972 {
973  ScViewData* pViewData = ScDocShell::GetViewData();
974 
975  if (!pViewData)
976  return;
977 
978  ScTabView* pTabView = pViewData->GetView();
979  if (!pTabView)
980  return;
981 
982  pTabView->getRowColumnHeaders(rRectangle, rJsonWriter);
983 }
984 
985 OString ScModelObj::getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden,
986  bool bFiltered, bool bGroups)
987 {
988  ScViewData* pViewData = ScDocShell::GetViewData();
989 
990  if (!pViewData)
991  return "";
992 
993  ScTabView* pTabView = pViewData->GetView();
994  if (!pTabView)
995  return "";
996 
997  return pTabView->getSheetGeometryData(bColumns, bRows, bSizes, bHidden, bFiltered, bGroups);
998 }
999 
1001 {
1002  SolarMutexGuard aGuard;
1003 
1004  ScViewData* pViewData = ScDocShell::GetViewData();
1005 
1006  if (!pViewData)
1007  return;
1008 
1009  ScGridWindow* pGridWindow = pViewData->GetActiveWin();
1010  if (!pGridWindow)
1011  return;
1012 
1013  rJsonWriter.put("commandName", ".uno:CellCursor");
1014  rJsonWriter.put("commandValues", pGridWindow->getCellCursor());
1015 }
1016 
1018 {
1019  SolarMutexGuard aGuard;
1020 
1021  ScViewData* pViewData = ScDocShell::GetViewData();
1022  if (!pViewData)
1023  return PointerStyle::Arrow;
1024 
1025  ScGridWindow* pGridWindow = pViewData->GetActiveWin();
1026  if (!pGridWindow)
1027  return PointerStyle::Arrow;
1028 
1029  return pGridWindow->GetPointer();
1030 }
1031 
1033 {
1034  if (pDocShell)
1035  {
1036  if (ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack())
1037  pChangeTrack->GetChangeTrackInfo(rJson);
1038  }
1039 }
1040 
1042 {
1043  ScViewData* pViewData = ScDocShell::GetViewData();
1044  if (!pViewData)
1045  return;
1046 
1047  // set the PgUp/PgDown offset
1048  pViewData->ForcePageUpDownOffset(rRectangle.GetHeight());
1049 
1050  // Store the visible area so that we can use at places like shape insertion
1051  pViewData->setLOKVisibleArea(rRectangle);
1052 
1054  comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs))
1055  {
1056  ScTabView* pTabView = pViewData->GetView();
1057  if (pTabView)
1058  pTabView->extendTiledAreaIfNeeded();
1059  }
1060 }
1061 
1062 void ScModelObj::setOutlineState(bool bColumn, int nLevel, int nIndex, bool bHidden)
1063 {
1064  ScViewData* pViewData = ScDocShell::GetViewData();
1065 
1066  if (!pViewData)
1067  return;
1068 
1069  ScDBFunc* pFunc = pViewData->GetView();
1070 
1071  if (pFunc)
1072  pFunc->SetOutlineState(bColumn, nLevel, nIndex, bHidden);
1073 }
1074 
1076 {
1077  if (!pDocShell)
1078  return;
1079 
1080  ScDocument& rDoc = pDocShell->GetDocument();
1081  std::vector<sc::NoteEntry> aNotes;
1082  rDoc.GetAllNoteEntries(aNotes);
1083 
1084  auto commentsNode = rJsonWriter.startNode("comments");
1085  for (const sc::NoteEntry& aNote : aNotes)
1086  {
1087  auto commentNode = rJsonWriter.startNode("");
1088 
1089  rJsonWriter.put("id", aNote.mpNote->GetId());
1090  rJsonWriter.put("tab", aNote.maPos.Tab());
1091  rJsonWriter.put("author", aNote.mpNote->GetAuthor());
1092  rJsonWriter.put("dateTime", aNote.mpNote->GetDate());
1093  rJsonWriter.put("text", aNote.mpNote->GetText());
1094 
1095  // Calculating the cell cursor position
1096  ScViewData* pViewData = ScDocShell::GetViewData();
1097  ScGridWindow* pGridWindow = pViewData->GetActiveWin();
1098  if (pGridWindow)
1099  {
1100  SCCOL nX = aNote.maPos.Col();
1101  SCROW nY = aNote.maPos.Row();
1102  Point aScrPos = pViewData->GetScrPos(nX, nY, pViewData->GetActivePart(), true);
1103  long nSizeXPix;
1104  long nSizeYPix;
1105  pViewData->GetMergeSizePixel(nX, nY, nSizeXPix, nSizeYPix);
1106 
1107  double fPPTX = pViewData->GetPPTX();
1108  double fPPTY = pViewData->GetPPTY();
1109  tools::Rectangle aRect(Point(aScrPos.getX() / fPPTX, aScrPos.getY() / fPPTY),
1110  Size(nSizeXPix / fPPTX, nSizeYPix / fPPTY));
1111 
1112  rJsonWriter.put("cellPos", aRect.toString());
1113  }
1114  }
1115 }
1116 
1118 {
1119  if (!pDocShell)
1120  return;
1121 
1122  ScDocument& rDoc = pDocShell->GetDocument();
1123  std::vector<sc::NoteEntry> aNotes;
1124  rDoc.GetAllNoteEntries(aNotes);
1125 
1126  auto commentsNode = rJsonWriter.startNode("commentsPos");
1127  for (const sc::NoteEntry& aNote : aNotes)
1128  {
1129  auto commentNode = rJsonWriter.startNode("");
1130 
1131  rJsonWriter.put("id", aNote.mpNote->GetId());
1132  rJsonWriter.put("tab", aNote.maPos.Tab());
1133 
1134  // Calculating the cell cursor position
1135  ScViewData* pViewData = ScDocShell::GetViewData();
1136  ScGridWindow* pGridWindow = pViewData->GetActiveWin();
1137  if (pGridWindow)
1138  {
1139  SCCOL nX = aNote.maPos.Col();
1140  SCROW nY = aNote.maPos.Row();
1141  Point aScrPos = pViewData->GetScrPos(nX, nY, pViewData->GetActivePart(), true);
1142  long nSizeXPix;
1143  long nSizeYPix;
1144  pViewData->GetMergeSizePixel(nX, nY, nSizeXPix, nSizeYPix);
1145 
1146  double fPPTX = pViewData->GetPPTX();
1147  double fPPTY = pViewData->GetPPTY();
1148  tools::Rectangle aRect(Point(aScrPos.getX() / fPPTX, aScrPos.getY() / fPPTY),
1149  Size(nSizeXPix / fPPTX, nSizeYPix / fPPTY));
1150 
1151  rJsonWriter.put("cellPos", aRect.toString());
1152  }
1153  }
1154 }
1155 
1156 void ScModelObj::completeFunction(const OUString& rFunctionName)
1157 {
1158  ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1159  if (pHdl)
1160  {
1161  assert(!rFunctionName.isEmpty());
1162  pHdl->LOKPasteFunctionData(rFunctionName);
1163  }
1164 }
1165 
1166 void ScModelObj::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& /*rArguments*/)
1167 {
1168  SolarMutexGuard aGuard;
1169 
1170  // disable word autocompletion
1171  ScAppOptions aAppOptions( SC_MOD()->GetAppOptions() );
1172  aAppOptions.SetAutoComplete(false);
1173  SC_MOD()->SetAppOptions(aAppOptions);
1174 
1175  // show us the text exactly
1176  ScInputOptions aInputOptions(SC_MOD()->GetInputOptions());
1177  aInputOptions.SetTextWysiwyg(true);
1178  aInputOptions.SetReplaceCellsWarn(false);
1179  SC_MOD()->SetInputOptions(aInputOptions);
1181 
1182  // when the "This document may contain formatting or content that cannot
1183  // be saved..." dialog appears, it is auto-cancelled with tiled rendering,
1184  // causing 'Save' being disabled; so let's always save to the original
1185  // format
1187 }
1188 
1190 {
1191  SC_QUERYINTERFACE( sheet::XSpreadsheetDocument )
1192  SC_QUERYINTERFACE( document::XActionLockable )
1193  SC_QUERYINTERFACE( sheet::XCalculatable )
1194  SC_QUERYINTERFACE( util::XProtectable )
1195  SC_QUERYINTERFACE( drawing::XDrawPagesSupplier )
1196  SC_QUERYINTERFACE( sheet::XGoalSeek )
1197  SC_QUERYINTERFACE( sheet::XConsolidatable )
1198  SC_QUERYINTERFACE( sheet::XDocumentAuditing )
1199  SC_QUERYINTERFACE( style::XStyleFamiliesSupplier )
1200  SC_QUERYINTERFACE( view::XRenderable )
1201  SC_QUERYINTERFACE( document::XLinkTargetSupplier )
1202  SC_QUERYINTERFACE( beans::XPropertySet )
1203  SC_QUERYINTERFACE( lang::XMultiServiceFactory )
1204  SC_QUERYINTERFACE( lang::XServiceInfo )
1205  SC_QUERYINTERFACE( util::XChangesNotifier )
1206  SC_QUERYINTERFACE( sheet::opencl::XOpenCLSelection )
1207  SC_QUERYINTERFACE( chart2::XDataProviderAccess )
1208 
1209  uno::Any aRet(SfxBaseModel::queryInterface( rType ));
1210  if ( !aRet.hasValue()
1217  {
1218  GetFormatter();
1219  if ( xNumberAgg.is() )
1220  aRet = xNumberAgg->queryAggregation( rType );
1221  }
1222 
1223  return aRet;
1224 }
1225 
1226 void SAL_CALL ScModelObj::acquire() throw()
1227 {
1229 }
1230 
1231 void SAL_CALL ScModelObj::release() throw()
1232 {
1234 }
1235 
1236 uno::Sequence<uno::Type> SAL_CALL ScModelObj::getTypes()
1237 {
1238  static const uno::Sequence<uno::Type> aTypes = [&]()
1239  {
1240  uno::Sequence<uno::Type> aAggTypes;
1241  if ( GetFormatter().is() )
1242  {
1244  uno::Any aNumProv(xNumberAgg->queryAggregation(rProvType));
1245  if(auto xNumProv
1246  = o3tl::tryAccess<uno::Reference<lang::XTypeProvider>>(aNumProv))
1247  {
1248  aAggTypes = (*xNumProv)->getTypes();
1249  }
1250  }
1253  aAggTypes,
1254  uno::Sequence<uno::Type>
1255  {
1272  } );
1273  }();
1274  return aTypes;
1275 }
1276 
1277 uno::Sequence<sal_Int8> SAL_CALL ScModelObj::getImplementationId()
1278 {
1279  return css::uno::Sequence<sal_Int8>();
1280 }
1281 
1282 void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1283 {
1284  // Not interested in reference update hints here
1285 
1286  const SfxHintId nId = rHint.GetId();
1287  if ( nId == SfxHintId::Dying )
1288  {
1289  pDocShell = nullptr; // has become invalid
1290  if (xNumberAgg.is())
1291  {
1292  SvNumberFormatsSupplierObj* pNumFmt =
1293  comphelper::getUnoTunnelImplementation<SvNumberFormatsSupplierObj>(
1294  uno::Reference<util::XNumberFormatsSupplier>(xNumberAgg, uno::UNO_QUERY) );
1295  if ( pNumFmt )
1296  pNumFmt->SetNumberFormatter( nullptr );
1297  }
1298 
1299  pPrintFuncCache.reset(); // must be deleted because it has a pointer to the DocShell
1300  m_pPrintState.reset();
1301  }
1302  else if ( nId == SfxHintId::DataChanged )
1303  {
1304  // cached data for rendering become invalid when contents change
1305  // (if a broadcast is added to SetDrawModified, is has to be tested here, too)
1306 
1307  pPrintFuncCache.reset();
1308  m_pPrintState.reset();
1309 
1310  // handle "OnCalculate" sheet events (search also for VBA event handlers)
1311  if ( pDocShell )
1312  {
1313  ScDocument& rDoc = pDocShell->GetDocument();
1314  if ( rDoc.GetVbaEventProcessor().is() )
1315  {
1316  // If the VBA event processor is set, HasAnyCalcNotification is much faster than HasAnySheetEventScript
1319  }
1320  else
1321  {
1324  }
1325  }
1326  }
1327 
1328  // always call parent - SfxBaseModel might need to handle the same hints again
1329  SfxBaseModel::Notify( rBC, rHint ); // SfxBaseModel is derived from SfxListener
1330 }
1331 
1332 // XSpreadsheetDocument
1333 
1334 uno::Reference<sheet::XSpreadsheets> SAL_CALL ScModelObj::getSheets()
1335 {
1336  SolarMutexGuard aGuard;
1337  if (pDocShell)
1338  return new ScTableSheetsObj(pDocShell);
1339  return nullptr;
1340 }
1341 
1342 css::uno::Reference< ::css::chart2::data::XDataProvider > SAL_CALL ScModelObj::createDataProvider()
1343 {
1344  if (pDocShell)
1345  {
1346  return css::uno::Reference< ::css::chart2::data::XDataProvider > (
1348  }
1349  return nullptr;
1350 }
1351 
1352 // XStyleFamiliesSupplier
1353 
1354 uno::Reference<container::XNameAccess> SAL_CALL ScModelObj::getStyleFamilies()
1355 {
1356  SolarMutexGuard aGuard;
1357  if (pDocShell)
1358  return new ScStyleFamiliesObj(pDocShell);
1359  return nullptr;
1360 }
1361 
1362 // XRenderable
1363 
1364 static OutputDevice* lcl_GetRenderDevice( const uno::Sequence<beans::PropertyValue>& rOptions )
1365 {
1366  OutputDevice* pRet = nullptr;
1367  for (const beans::PropertyValue& rProp : rOptions)
1368  {
1369  const OUString & rPropName = rProp.Name;
1370 
1371  if (rPropName == SC_UNONAME_RENDERDEV)
1372  {
1373  uno::Reference<awt::XDevice> xRenderDevice(rProp.Value, uno::UNO_QUERY);
1374  if ( xRenderDevice.is() )
1375  {
1376  VCLXDevice* pDevice = comphelper::getUnoTunnelImplementation<VCLXDevice>( xRenderDevice );
1377  if ( pDevice )
1378  {
1379  pRet = pDevice->GetOutputDevice().get();
1380  pRet->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
1381  }
1382  }
1383  }
1384  }
1385  return pRet;
1386 }
1387 
1388 static bool lcl_ParseTarget( const OUString& rTarget, ScRange& rTargetRange, tools::Rectangle& rTargetRect,
1389  bool& rIsSheet, ScDocument* pDoc, SCTAB nSourceTab )
1390 {
1391  // test in same order as in SID_CURRENTCELL execute
1392 
1393  ScAddress aAddress;
1394  SCTAB nNameTab;
1395  sal_Int32 nNumeric = 0;
1396 
1397  bool bRangeValid = false;
1398  bool bRectValid = false;
1399 
1400  if ( rTargetRange.Parse( rTarget, pDoc ) & ScRefFlags::VALID )
1401  {
1402  bRangeValid = true; // range reference
1403  }
1404  else if ( aAddress.Parse( rTarget, pDoc ) & ScRefFlags::VALID )
1405  {
1406  rTargetRange = aAddress;
1407  bRangeValid = true; // cell reference
1408  }
1409  else if ( ScRangeUtil::MakeRangeFromName( rTarget, pDoc, nSourceTab, rTargetRange ) ||
1410  ScRangeUtil::MakeRangeFromName( rTarget, pDoc, nSourceTab, rTargetRange, RUTL_DBASE ) )
1411  {
1412  bRangeValid = true; // named range or database range
1413  }
1414  else if ( comphelper::string::isdigitAsciiString(rTarget) &&
1415  ( nNumeric = rTarget.toInt32() ) > 0 && nNumeric <= pDoc->MaxRow()+1 )
1416  {
1417  // row number is always mapped to cell A(row) on the same sheet
1418  rTargetRange = ScAddress( 0, static_cast<SCROW>(nNumeric-1), nSourceTab ); // target row number is 1-based
1419  bRangeValid = true; // row number
1420  }
1421  else if ( pDoc->GetTable( rTarget, nNameTab ) )
1422  {
1423  rTargetRange = ScAddress(0,0,nNameTab);
1424  bRangeValid = true; // sheet name
1425  rIsSheet = true; // needs special handling (first page of the sheet)
1426  }
1427  else
1428  {
1429  // look for named drawing object
1430 
1431  ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
1432  if ( pDrawLayer )
1433  {
1434  SCTAB nTabCount = pDoc->GetTableCount();
1435  for (SCTAB i=0; i<nTabCount && !bRangeValid; i++)
1436  {
1437  SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
1438  OSL_ENSURE(pPage,"Page ?");
1439  if (pPage)
1440  {
1441  SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
1442  SdrObject* pObject = aIter.Next();
1443  while (pObject && !bRangeValid)
1444  {
1445  if ( ScDrawLayer::GetVisibleName( pObject ) == rTarget )
1446  {
1447  rTargetRect = pObject->GetLogicRect(); // 1/100th mm
1448  rTargetRange = pDoc->GetRange( i, rTargetRect ); // underlying cells
1449  bRangeValid = bRectValid = true; // rectangle is valid
1450  }
1451  pObject = aIter.Next();
1452  }
1453  }
1454  }
1455  }
1456  }
1457  if ( bRangeValid && !bRectValid )
1458  {
1459  // get rectangle for cell range
1460  rTargetRect = pDoc->GetMMRect( rTargetRange.aStart.Col(), rTargetRange.aStart.Row(),
1461  rTargetRange.aEnd.Col(), rTargetRange.aEnd.Row(),
1462  rTargetRange.aStart.Tab() );
1463  }
1464 
1465  return bRangeValid;
1466 }
1467 
1469  const uno::Sequence< beans::PropertyValue >& rOptions,
1470  ScMarkData& rMark,
1471  ScPrintSelectionStatus& rStatus, OUString& rPagesStr,
1472  bool& rbRenderToGraphic ) const
1473 {
1474  OSL_ENSURE( !rMark.IsMarked() && !rMark.IsMultiMarked(), "FillRenderMarkData: MarkData must be empty" );
1475  OSL_ENSURE( pDocShell, "FillRenderMarkData: DocShell must be set" );
1476 
1477  bool bDone = false;
1478 
1479  uno::Reference<frame::XController> xView;
1480 
1481  // defaults when no options are passed: all sheets, include empty pages
1482  bool bSelectedSheetsOnly = false;
1483  bool bSuppressEmptyPages = true;
1484 
1485  bool bHasPrintContent = false;
1486  sal_Int32 nPrintContent = 0; // all sheets / selected sheets / selected cells
1487  sal_Int32 nPrintRange = 0; // all pages / pages
1488  sal_Int32 nEOContent = 0; // even pages / odd pages
1489  OUString aPageRange; // "pages" edit value
1490 
1491  for( const auto& rOption : rOptions )
1492  {
1493  if ( rOption.Name == "IsOnlySelectedSheets" )
1494  {
1495  rOption.Value >>= bSelectedSheetsOnly;
1496  }
1497  else if ( rOption.Name == "IsSuppressEmptyPages" )
1498  {
1499  rOption.Value >>= bSuppressEmptyPages;
1500  }
1501  else if ( rOption.Name == "PageRange" )
1502  {
1503  rOption.Value >>= aPageRange;
1504  }
1505  else if ( rOption.Name == "PrintRange" )
1506  {
1507  rOption.Value >>= nPrintRange;
1508  }
1509  else if ( rOption.Name == "EvenOdd" )
1510  {
1511  rOption.Value >>= nEOContent;
1512  }
1513  else if ( rOption.Name == "PrintContent" )
1514  {
1515  bHasPrintContent = true;
1516  rOption.Value >>= nPrintContent;
1517  }
1518  else if ( rOption.Name == "View" )
1519  {
1520  rOption.Value >>= xView;
1521  }
1522  else if ( rOption.Name == "RenderToGraphic" )
1523  {
1524  rOption.Value >>= rbRenderToGraphic;
1525  }
1526  }
1527 
1528  // "Print Content" selection wins over "Selected Sheets" option
1529  if ( bHasPrintContent )
1530  bSelectedSheetsOnly = ( nPrintContent != 0 );
1531 
1532  uno::Reference<uno::XInterface> xInterface(aSelection, uno::UNO_QUERY);
1533  if ( xInterface.is() )
1534  {
1535  ScCellRangesBase* pSelObj = comphelper::getUnoTunnelImplementation<ScCellRangesBase>( xInterface );
1536  uno::Reference< drawing::XShapes > xShapes( xInterface, uno::UNO_QUERY );
1537  if ( pSelObj && pSelObj->GetDocShell() == pDocShell )
1538  {
1539  bool bSheet = ( comphelper::getUnoTunnelImplementation<ScTableSheetObj>( xInterface ) != nullptr );
1540  bool bCursor = pSelObj->IsCursorOnly();
1541  const ScRangeList& rRanges = pSelObj->GetRangeList();
1542 
1543  rMark.MarkFromRangeList( rRanges, false );
1544  rMark.MarkToSimple();
1545 
1546  if ( rMark.IsMultiMarked() )
1547  {
1548  // #i115266# copy behavior of old printing:
1549  // treat multiple selection like a single selection with the enclosing range
1550  ScRange aMultiMarkArea;
1551  rMark.GetMultiMarkArea( aMultiMarkArea );
1552  rMark.ResetMark();
1553  rMark.SetMarkArea( aMultiMarkArea );
1554  }
1555 
1556  if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
1557  {
1558  // a sheet object is treated like an empty selection: print the used area of the sheet
1559 
1560  if ( bCursor || bSheet ) // nothing selected -> use whole tables
1561  {
1562  rMark.ResetMark(); // doesn't change table selection
1563  rStatus.SetMode( SC_PRINTSEL_CURSOR );
1564  }
1565  else
1566  rStatus.SetMode( SC_PRINTSEL_RANGE );
1567 
1568  rStatus.SetRanges( rRanges );
1569  bDone = true;
1570  }
1571  // multi selection isn't supported
1572  }
1573  else if( xShapes.is() )
1574  {
1575  //print a selected ole object
1576  // multi selection isn't supported yet
1577  uno::Reference< drawing::XShape > xShape( xShapes->getByIndex(0), uno::UNO_QUERY );
1578  SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( xShape );
1579  if( pShape )
1580  {
1581  SdrObject *pSdrObj = pShape->GetSdrObject();
1582  if( pDocShell )
1583  {
1584  ScDocument& rDoc = pDocShell->GetDocument();
1585  if( pSdrObj )
1586  {
1587  tools::Rectangle aObjRect = pSdrObj->GetCurrentBoundRect();
1588  SCTAB nCurrentTab = ScDocShell::GetCurTab();
1589  ScRange aRange = rDoc.GetRange( nCurrentTab, aObjRect );
1590  rMark.SetMarkArea( aRange );
1591 
1592  if( rMark.IsMarked() && !rMark.IsMultiMarked() )
1593  {
1595  bDone = true;
1596  }
1597  }
1598  }
1599  }
1600  }
1601  else if ( comphelper::getUnoTunnelImplementation<ScModelObj>( xInterface ) == this )
1602  {
1603  // render the whole document
1604  // -> no selection, all sheets
1605 
1606  SCTAB nTabCount = pDocShell->GetDocument().GetTableCount();
1607  for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
1608  rMark.SelectTable( nTab, true );
1609  rStatus.SetMode( SC_PRINTSEL_DOCUMENT );
1610  bDone = true;
1611  }
1612  // other selection types aren't supported
1613  }
1614 
1615  // restrict to selected sheets if a view is available
1616  uno::Reference<sheet::XSelectedSheetsSupplier> xSelectedSheets(xView, uno::UNO_QUERY);
1617  if (bSelectedSheetsOnly && xSelectedSheets.is())
1618  {
1619  const uno::Sequence<sal_Int32> aSelected = xSelectedSheets->getSelectedSheets();
1620  ScMarkData::MarkedTabsType aSelectedTabs;
1621  SCTAB nMaxTab = pDocShell->GetDocument().GetTableCount() -1;
1622  for (const auto& rSelected : aSelected)
1623  {
1624  SCTAB nSelected = static_cast<SCTAB>(rSelected);
1625  if (ValidTab(nSelected, nMaxTab))
1626  aSelectedTabs.insert(nSelected);
1627  }
1628  rMark.SetSelectedTabs(aSelectedTabs);
1629  }
1630 
1631  ScPrintOptions aNewOptions;
1632  aNewOptions.SetSkipEmpty( bSuppressEmptyPages );
1633  aNewOptions.SetAllSheets( !bSelectedSheetsOnly );
1634  rStatus.SetOptions( aNewOptions );
1635 
1636  // "PrintRange" enables (1) or disables (0) the "PageRange" edit
1637  if ( nPrintRange == 1 )
1638  rPagesStr = aPageRange;
1639  else
1640  rPagesStr.clear();
1641 
1642  return bDone;
1643 }
1644 
1645 sal_Int32 SAL_CALL ScModelObj::getRendererCount(const uno::Any& aSelection,
1646  const uno::Sequence<beans::PropertyValue>& rOptions)
1647 {
1648  SolarMutexGuard aGuard;
1649  if (!pDocShell)
1650  {
1651  throw lang::DisposedException( OUString(),
1652  static_cast< sheet::XSpreadsheetDocument* >(this) );
1653  }
1654 
1655  ScMarkData aMark(GetDocument()->GetSheetLimits());
1656  ScPrintSelectionStatus aStatus;
1657  OUString aPagesStr;
1658  bool bRenderToGraphic = false;
1659  if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr, bRenderToGraphic ) )
1660  return 0;
1661 
1662  // The same ScPrintFuncCache object in pPrintFuncCache is used as long as
1663  // the same selection is used (aStatus) and the document isn't changed
1664  // (pPrintFuncCache is cleared in Notify handler)
1665 
1666  if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
1667  {
1668  pPrintFuncCache.reset(new ScPrintFuncCache( pDocShell, aMark, aStatus ));
1669  }
1670  sal_Int32 nPages = pPrintFuncCache->GetPageCount();
1671 
1672  m_pPrintState.reset();
1673  maValidPages.clear();
1674 
1675  sal_Int32 nContent = 0;
1676  sal_Int32 nEOContent = 0;
1677  bool bSinglePageSheets = false;
1678  for ( const auto& rValue : rOptions)
1679  {
1680  if ( rValue.Name == "PrintRange" )
1681  {
1682  rValue.Value >>= nContent;
1683  }
1684  else if ( rValue.Name == "SinglePageSheets" )
1685  {
1686  rValue.Value >>= bSinglePageSheets;
1687  }
1688  else if ( rValue.Name == "EvenOdd" )
1689  {
1690  rValue.Value >>= nEOContent;
1691  }
1692  }
1693 
1694  if (bSinglePageSheets)
1695  {
1696  return pDocShell->GetDocument().GetTableCount();
1697  }
1698 
1699  bool bIsPrintEvenPages = (nEOContent != 1 && nContent == 0) || nContent != 0;
1700  bool bIsPrintOddPages = (nEOContent != 2 && nContent == 0) || nContent != 0;
1701 
1702  for ( sal_Int32 nPage = 1; nPage <= nPages; nPage++ )
1703  {
1704  if ( (bIsPrintEvenPages && IsOnEvenPage( nPage )) || (bIsPrintOddPages && !IsOnEvenPage( nPage )) )
1705  maValidPages.push_back( nPage );
1706  }
1707 
1708  sal_Int32 nSelectCount = static_cast<sal_Int32>( maValidPages.size() );
1709 
1710  if ( nEOContent == 1 || nEOContent == 2 ) // even pages / odd pages
1711  return nSelectCount;
1712 
1713  if ( !aPagesStr.isEmpty() )
1714  {
1715  StringRangeEnumerator aRangeEnum( aPagesStr, 0, nPages-1 );
1716  nSelectCount = aRangeEnum.size();
1717  }
1718  return (nSelectCount > 0) ? nSelectCount : 1;
1719 }
1720 
1721 static sal_Int32 lcl_GetRendererNum( sal_Int32 nSelRenderer, const OUString& rPagesStr, sal_Int32 nTotalPages )
1722 {
1723  if ( rPagesStr.isEmpty() )
1724  return nSelRenderer;
1725 
1726  StringRangeEnumerator aRangeEnum( rPagesStr, 0, nTotalPages-1 );
1727  StringRangeEnumerator::Iterator aIter = aRangeEnum.begin();
1728  StringRangeEnumerator::Iterator aEnd = aRangeEnum.end();
1729  for ( ; nSelRenderer > 0 && aIter != aEnd; --nSelRenderer )
1730  ++aIter;
1731 
1732  return *aIter; // returns -1 if reached the end
1733 }
1734 
1735 static bool lcl_renderSelectionToGraphic( bool bRenderToGraphic, const ScPrintSelectionStatus& rStatus )
1736 {
1737  return bRenderToGraphic && rStatus.GetMode() == SC_PRINTSEL_RANGE;
1738 }
1739 
1740 uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 nSelRenderer,
1741  const uno::Any& aSelection, const uno::Sequence<beans::PropertyValue>& rOptions )
1742 {
1743  SolarMutexGuard aGuard;
1744  if (!pDocShell)
1745  {
1746  throw lang::DisposedException( OUString(),
1747  static_cast< sheet::XSpreadsheetDocument* >(this) );
1748  }
1749 
1751  ScPrintSelectionStatus aStatus;
1752  OUString aPagesStr;
1753  // #i115266# if FillRenderMarkData fails, keep nTotalPages at 0, but still handle getRenderer(0) below
1754  long nTotalPages = 0;
1755  bool bRenderToGraphic = false;
1756  bool bSinglePageSheets = false;
1757  if ( FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr, bRenderToGraphic ) )
1758  {
1759  if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
1760  {
1761  pPrintFuncCache.reset(new ScPrintFuncCache( pDocShell, aMark, aStatus ));
1762  }
1763  nTotalPages = pPrintFuncCache->GetPageCount();
1764  }
1765 
1766  for ( const auto& rValue : rOptions)
1767  {
1768  if ( rValue.Name == "SinglePageSheets" )
1769  {
1770  rValue.Value >>= bSinglePageSheets;
1771  break;
1772  }
1773  }
1774 
1775  if (bSinglePageSheets)
1776  nTotalPages = pDocShell->GetDocument().GetTableCount();
1777 
1778  sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages );
1779 
1780  if ( nRenderer < 0 )
1781  {
1782  if ( nSelRenderer != 0 )
1783  throw lang::IllegalArgumentException();
1784 
1785  // getRenderer(0) is used to query the settings, so it must always return something
1786 
1787  awt::Size aPageSize;
1788  if (lcl_renderSelectionToGraphic( bRenderToGraphic, aStatus))
1789  {
1790  assert( aMark.IsMarked());
1791  ScRange aRange;
1792  aMark.GetMarkArea( aRange );
1794  aRange.aStart.Col(), aRange.aStart.Row(),
1795  aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab()));
1796  aPageSize.Width = aMMRect.GetWidth();
1797  aPageSize.Height = aMMRect.GetHeight();
1798  }
1799  else
1800  {
1801  SCTAB const nCurTab = 0;
1802  ScPrintFunc aDefaultFunc( pDocShell, pDocShell->GetPrinter(), nCurTab );
1803  Size aTwips = aDefaultFunc.GetPageSize();
1804  aPageSize.Width = TwipsToHMM( aTwips.Width());
1805  aPageSize.Height = TwipsToHMM( aTwips.Height());
1806  }
1807 
1808  uno::Sequence<beans::PropertyValue> aSequence( comphelper::InitPropertySequence({
1809  { SC_UNONAME_PAGESIZE, uno::Any(aPageSize) }
1810  }));
1811 
1812  if( ! pPrinterOptions )
1813  pPrinterOptions.reset(new ScPrintUIOptions);
1814  else
1815  pPrinterOptions->SetDefaults();
1816  pPrinterOptions->appendPrintUIOptions( aSequence );
1817  return aSequence;
1818 
1819  }
1820 
1821  // printer is used as device (just for page layout), draw view is not needed
1822 
1823  SCTAB nTab;
1824  if (bSinglePageSheets)
1825  nTab = nSelRenderer;
1826  else if ( !maValidPages.empty() )
1827  nTab = pPrintFuncCache->GetTabForPage( maValidPages.at( nRenderer )-1 );
1828  else
1829  nTab = pPrintFuncCache->GetTabForPage( nRenderer );
1830 
1831 
1832  ScRange aRange;
1833  const ScRange* pSelRange = nullptr;
1834  if ( bSinglePageSheets )
1835  {
1836  awt::Size aPageSize;
1837  SCCOL nStartCol;
1838  SCROW nStartRow;
1839  const ScDocument* pDocument = &pDocShell->GetDocument();
1840  pDocument->GetDataStart( nTab, nStartCol, nStartRow );
1841  SCCOL nEndCol;
1842  SCROW nEndRow;
1843  pDocument->GetPrintArea( nTab, nEndCol, nEndRow );
1844 
1845  aRange.aStart = ScAddress(nStartCol, nStartRow, nTab);
1846  aRange.aEnd = ScAddress(nEndCol, nEndRow, nTab);
1847 
1848  table::CellRangeAddress aRangeAddress( nTab,
1849  aRange.aStart.Col(), aRange.aStart.Row(),
1850  aRange.aEnd.Col(), aRange.aEnd.Row() );
1852  aRange.aStart.Col(), aRange.aStart.Row(),
1853  aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab()));
1854 
1855  aPageSize.Width = aMMRect.GetWidth();
1856  aPageSize.Height = aMMRect.GetHeight();
1857 
1858  awt::Size aCalcPageSize ( aMMRect.GetSize().Width(), aMMRect.GetSize().Height() );
1859  awt::Point aCalcPagePos( aMMRect.getX(), aMMRect.getY() );
1860 
1861  uno::Sequence<beans::PropertyValue> aSequence(5);
1862  beans::PropertyValue* pArray = aSequence.getArray();
1863  pArray[0].Name = SC_UNONAME_PAGESIZE;
1864  pArray[0].Value <<= aPageSize;
1865  // #i111158# all positions are relative to the whole page, including non-printable area
1866  pArray[1].Name = SC_UNONAME_INC_NP_AREA;
1867  pArray[1].Value <<= true;
1868  pArray[2].Name = SC_UNONAME_SOURCERANGE;
1869  pArray[2].Value <<= aRangeAddress;
1870  pArray[3].Name = SC_UNONAME_CALCPAGESIZE;
1871  pArray[3].Value <<= aCalcPageSize;
1872  pArray[4].Name = SC_UNONAME_CALCPAGEPOS;
1873  pArray[4].Value <<= aCalcPagePos;
1874 
1875  if( ! pPrinterOptions )
1876  pPrinterOptions.reset(new ScPrintUIOptions);
1877  else
1878  pPrinterOptions->SetDefaults();
1879  pPrinterOptions->appendPrintUIOptions( aSequence );
1880  return aSequence;
1881  }
1882  else if ( aMark.IsMarked() )
1883  {
1884  aMark.GetMarkArea( aRange );
1885  pSelRange = &aRange;
1886  }
1887 
1888  awt::Size aPageSize;
1889  bool bWasCellRange = false;
1890  ScRange aCellRange;
1891  if (lcl_renderSelectionToGraphic( bRenderToGraphic, aStatus))
1892  {
1893  bWasCellRange = true;
1894  aCellRange = aRange;
1896  aRange.aStart.Col(), aRange.aStart.Row(),
1897  aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab()));
1898  aPageSize.Width = aMMRect.GetWidth();
1899  aPageSize.Height = aMMRect.GetHeight();
1900  }
1901  else
1902  {
1903  std::unique_ptr<ScPrintFunc, o3tl::default_delete<ScPrintFunc>> pPrintFunc;
1904  if (m_pPrintState && m_pPrintState->nPrintTab == nTab)
1905  pPrintFunc.reset(new ScPrintFunc(pDocShell, pDocShell->GetPrinter(), *m_pPrintState, &aStatus.GetOptions()));
1906  else
1907  pPrintFunc.reset(new ScPrintFunc(pDocShell, pDocShell->GetPrinter(), nTab,
1908  pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions()));
1909  pPrintFunc->SetRenderFlag( true );
1910 
1911  sal_Int32 nContent = 0;
1912  sal_Int32 nEOContent = 0;
1913  for ( const auto& rValue : rOptions)
1914  {
1915  if ( rValue.Name == "PrintRange" )
1916  {
1917  rValue.Value >>= nContent;
1918  }
1919  else if ( rValue.Name == "EvenOdd" )
1920  {
1921  rValue.Value >>= nEOContent;
1922  }
1923  }
1924 
1925  MultiSelection aPage;
1926  aPage.SetTotalRange( Range(0,RANGE_MAX) );
1927 
1928  bool bOddOrEven = (nContent == 0 && nEOContent == 1) || (nContent == 1 && nEOContent == 2); // even pages or odd pages
1929  // tdf#127682 when odd/even allow nRenderer of 0 even when maValidPages is empty
1930  // to allow PrinterController::abortJob to spool an empty page as part of
1931  // its abort procedure
1932  if (bOddOrEven && !maValidPages.empty())
1933  aPage.Select( maValidPages.at(nRenderer) );
1934  else
1935  aPage.Select( nRenderer+1 );
1936 
1937  long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab );
1938  long nTabStart = pPrintFuncCache->GetTabStart( nTab );
1939 
1940  (void)pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart, false, nullptr );
1941 
1942  bWasCellRange = pPrintFunc->GetLastSourceRange( aCellRange );
1943  Size aTwips = pPrintFunc->GetPageSize();
1944 
1945  if (!m_pPrintState)
1946  {
1947  m_pPrintState.reset(new ScPrintState());
1948  pPrintFunc->GetPrintState(*m_pPrintState, true);
1949  }
1950 
1951  aPageSize.Width = TwipsToHMM( aTwips.Width());
1952  aPageSize.Height = TwipsToHMM( aTwips.Height());
1953  }
1954 
1955  long nPropCount = bWasCellRange ? 5 : 4;
1956  uno::Sequence<beans::PropertyValue> aSequence(nPropCount);
1957  beans::PropertyValue* pArray = aSequence.getArray();
1958  pArray[0].Name = SC_UNONAME_PAGESIZE;
1959  pArray[0].Value <<= aPageSize;
1960  // #i111158# all positions are relative to the whole page, including non-printable area
1961  pArray[1].Name = SC_UNONAME_INC_NP_AREA;
1962  pArray[1].Value <<= true;
1963  if ( bWasCellRange )
1964  {
1965  table::CellRangeAddress aRangeAddress( nTab,
1966  aCellRange.aStart.Col(), aCellRange.aStart.Row(),
1967  aCellRange.aEnd.Col(), aCellRange.aEnd.Row() );
1969  aCellRange.aStart.Col(), aCellRange.aStart.Row(),
1970  aCellRange.aEnd.Col(), aCellRange.aEnd.Row(), aCellRange.aStart.Tab()));
1971 
1972  awt::Size aCalcPageSize ( aMMRect.GetSize().Width(), aMMRect.GetSize().Height() );
1973  awt::Point aCalcPagePos( aMMRect.getX(), aMMRect.getY() );
1974 
1975  pArray[2].Name = SC_UNONAME_SOURCERANGE;
1976  pArray[2].Value <<= aRangeAddress;
1977  pArray[3].Name = SC_UNONAME_CALCPAGESIZE;
1978  pArray[3].Value <<= aCalcPageSize;
1979  pArray[4].Name = SC_UNONAME_CALCPAGEPOS;
1980  pArray[4].Value <<= aCalcPagePos;
1981  }
1982 
1983  if( ! pPrinterOptions )
1984  pPrinterOptions.reset(new ScPrintUIOptions);
1985  else
1986  pPrinterOptions->SetDefaults();
1987  pPrinterOptions->appendPrintUIOptions( aSequence );
1988  return aSequence;
1989 }
1990 
1991 void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelection,
1992  const uno::Sequence<beans::PropertyValue>& rOptions )
1993 {
1994  SolarMutexGuard aGuard;
1995  if (!pDocShell)
1996  {
1997  throw lang::DisposedException( OUString(),
1998  static_cast< sheet::XSpreadsheetDocument* >(this) );
1999  }
2000 
2002  ScPrintSelectionStatus aStatus;
2003  OUString aPagesStr;
2004  bool bRenderToGraphic = false;
2005  bool bSinglePageSheets = false;
2006  if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr, bRenderToGraphic ) )
2007  throw lang::IllegalArgumentException();
2008 
2009  if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
2010  {
2011  pPrintFuncCache.reset(new ScPrintFuncCache( pDocShell, aMark, aStatus ));
2012  }
2013  long nTotalPages = pPrintFuncCache->GetPageCount();
2014 
2015  for ( const auto& rValue : rOptions)
2016  {
2017  if ( rValue.Name == "SinglePageSheets" )
2018  {
2019  rValue.Value >>= bSinglePageSheets;
2020  break;
2021  }
2022  }
2023 
2024  if (bSinglePageSheets)
2025  nTotalPages = pDocShell->GetDocument().GetTableCount();
2026 
2027  sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages );
2028  if ( nRenderer < 0 )
2029  throw lang::IllegalArgumentException();
2030 
2031  OutputDevice* pDev = lcl_GetRenderDevice( rOptions );
2032  if ( !pDev )
2033  throw lang::IllegalArgumentException();
2034 
2035  ScDocument& rDoc = pDocShell->GetDocument();
2036 
2037  ScRange aRange;
2038  const ScRange* pSelRange = nullptr;
2039  if ( bSinglePageSheets )
2040  {
2041  awt::Size aPageSize;
2042  SCCOL nStartCol;
2043  SCROW nStartRow;
2044  rDoc.GetDataStart( nSelRenderer, nStartCol, nStartRow );
2045  SCCOL nEndCol;
2046  SCROW nEndRow;
2047  rDoc.GetPrintArea( nSelRenderer, nEndCol, nEndRow );
2048 
2049  aRange.aStart = ScAddress(nStartCol, nStartRow, nSelRenderer);
2050  aRange.aEnd = ScAddress(nEndCol, nEndRow, nSelRenderer);
2051 
2053  aRange.aStart.Col(), aRange.aStart.Row(),
2054  aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab()));
2055 
2056  aPageSize.Width = aMMRect.GetWidth();
2057  aPageSize.Height = aMMRect.GetHeight();
2058 
2059  //Set visible tab
2060  SCTAB nVisTab = rDoc.GetVisibleTab();
2061  if (nVisTab != nSelRenderer)
2062  {
2063  nVisTab = nSelRenderer;
2064  rDoc.SetVisibleTab(nVisTab);
2065  }
2066 
2067  pDocShell->DoDraw(pDev, Point(0,0), Size(aPageSize.Width, aPageSize.Height), JobSetup());
2068 
2069  return;
2070  }
2071  else if ( aMark.IsMarked() )
2072  {
2073  aMark.GetMarkArea( aRange );
2074  pSelRange = &aRange;
2075  }
2076 
2077  if (lcl_renderSelectionToGraphic( bRenderToGraphic, aStatus))
2078  {
2079  // Similar to as in and when calling ScTransferObj::PaintToDev()
2080 
2081  tools::Rectangle aBound( Point(), pDev->GetOutputSize());
2082 
2083  ScViewData aViewData(nullptr,nullptr);
2084  aViewData.InitData( &rDoc );
2085 
2086  aViewData.SetTabNo( aRange.aStart.Tab() );
2087  aViewData.SetScreen( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row() );
2088 
2089  const double nPrintFactor = 1.0; /* XXX: currently (2017-08-28) is not evaluated */
2090  // The bMetaFile argument maybe could be
2091  // pDev->GetConnectMetaFile() != nullptr
2092  // but for some yet unknown reason does not draw cell content if true.
2093  ScPrintFunc::DrawToDev( &rDoc, pDev, nPrintFactor, aBound, &aViewData, false /*bMetaFile*/ );
2094 
2095  return;
2096  }
2097 
2098  struct DrawViewKeeper
2099  {
2100  std::unique_ptr<FmFormView> mpDrawView;
2101  DrawViewKeeper() {}
2102  ~DrawViewKeeper()
2103  {
2104  if (mpDrawView)
2105  {
2106  mpDrawView->HideSdrPage();
2107  mpDrawView.reset();
2108  }
2109  }
2110  } aDrawViewKeeper;
2111 
2112  SCTAB nTab;
2113  if ( !maValidPages.empty() )
2114  nTab = pPrintFuncCache->GetTabForPage( maValidPages.at( nRenderer )-1 );
2115  else
2116  nTab = pPrintFuncCache->GetTabForPage( nRenderer );
2117 
2118  ScDrawLayer* pModel = rDoc.GetDrawLayer();
2119 
2120  if( pModel )
2121  {
2122  aDrawViewKeeper.mpDrawView.reset( new FmFormView(
2123  *pModel,
2124  pDev) );
2125  aDrawViewKeeper.mpDrawView->ShowSdrPage(aDrawViewKeeper.mpDrawView->GetModel()->GetPage(nTab));
2126  aDrawViewKeeper.mpDrawView->SetPrintPreview();
2127  }
2128 
2129  // to increase performance, ScPrintState might be used here for subsequent
2130  // pages of the same sheet
2131 
2132 
2133  std::unique_ptr<ScPrintFunc, o3tl::default_delete<ScPrintFunc>> pPrintFunc;
2134  if (m_pPrintState && m_pPrintState->nPrintTab == nTab
2135  && ! pSelRange) // tdf#120161 use selection to set required printed area
2136  pPrintFunc.reset(new ScPrintFunc(pDev, pDocShell, *m_pPrintState, &aStatus.GetOptions()));
2137  else
2138  pPrintFunc.reset(new ScPrintFunc(pDev, pDocShell, nTab, pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions()));
2139 
2140  pPrintFunc->SetDrawView( aDrawViewKeeper.mpDrawView.get() );
2141  pPrintFunc->SetRenderFlag( true );
2142  if( aStatus.GetMode() == SC_PRINTSEL_RANGE_EXCLUSIVELY_OLE_AND_DRAW_OBJECTS )
2143  pPrintFunc->SetExclusivelyDrawOleAndDrawObjects();
2144 
2145  sal_Int32 nContent = 0;
2146  sal_Int32 nEOContent = 0;
2147  for ( const auto& rValue : rOptions)
2148  {
2149  if ( rValue.Name == "PrintRange" )
2150  {
2151  rValue.Value >>= nContent;
2152  }
2153  else if ( rValue.Name == "EvenOdd" )
2154  {
2155  rValue.Value >>= nEOContent;
2156  }
2157  }
2158 
2159  MultiSelection aPage;
2160  aPage.SetTotalRange( Range(0,RANGE_MAX) );
2161 
2162  bool bOddOrEven = (nContent == 0 && nEOContent == 1) || (nContent == 0 && nEOContent == 2); // even pages or odd pages
2163  // tdf#127682 when odd/even allow nRenderer of 0 even when maValidPages is empty
2164  // to allow PrinterController::abortJob to spool an empty page as part of
2165  // its abort procedure
2166  if (bOddOrEven && !maValidPages.empty())
2167  aPage.Select( maValidPages.at( nRenderer ) );
2168  else
2169  aPage.Select( nRenderer+1 );
2170 
2171  long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab );
2172  long nTabStart = pPrintFuncCache->GetTabStart( nTab );
2173 
2174  vcl::PDFExtOutDevData* pPDFData = dynamic_cast< vcl::PDFExtOutDevData* >(pDev->GetExtOutDevData() );
2175  if ( nRenderer == nTabStart )
2176  {
2177  // first page of a sheet: add outline item for the sheet name
2178 
2179  if ( pPDFData && pPDFData->GetIsExportBookmarks() )
2180  {
2181  // the sheet starts at the top of the page
2182  tools::Rectangle aArea( pDev->PixelToLogic( tools::Rectangle( 0,0,0,0 ) ) );
2183  sal_Int32 nDestID = pPDFData->CreateDest( aArea );
2184  OUString aTabName;
2185  rDoc.GetName( nTab, aTabName );
2186  // top-level
2187  pPDFData->CreateOutlineItem( -1/*nParent*/, aTabName, nDestID );
2188  }
2189  // #i56629# add the named destination stuff
2190  if( pPDFData && pPDFData->GetIsExportNamedDestinations() )
2191  {
2192  tools::Rectangle aArea( pDev->PixelToLogic( tools::Rectangle( 0,0,0,0 ) ) );
2193  OUString aTabName;
2194  rDoc.GetName( nTab, aTabName );
2195  //need the PDF page number here
2196  pPDFData->CreateNamedDest( aTabName, aArea );
2197  }
2198  }
2199 
2200  (void)pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart, true, nullptr );
2201 
2202  if (!m_pPrintState)
2203  {
2204  m_pPrintState.reset(new ScPrintState());
2205  pPrintFunc->GetPrintState(*m_pPrintState, true);
2206  }
2207 
2208  // resolve the hyperlinks for PDF export
2209 
2210  if ( pPDFData && !pPDFData->GetBookmarks().empty() )
2211  {
2212  // iterate over the hyperlinks that were output for this page
2213 
2214  std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFData->GetBookmarks();
2215  for ( const auto& rBookmark : rBookmarks )
2216  {
2217  OUString aBookmark = rBookmark.aBookmark;
2218  if ( aBookmark.toChar() == '#' )
2219  {
2220  // try to resolve internal link
2221 
2222  OUString aTarget( aBookmark.copy( 1 ) );
2223 
2224  ScRange aTargetRange;
2225  tools::Rectangle aTargetRect; // 1/100th mm
2226  bool bIsSheet = false;
2227  bool bValid = lcl_ParseTarget( aTarget, aTargetRange, aTargetRect, bIsSheet, &rDoc, nTab );
2228 
2229  if ( bValid )
2230  {
2231  sal_Int32 nPage = -1;
2232  tools::Rectangle aArea;
2233  if ( bIsSheet )
2234  {
2235  // Get first page for sheet (if nothing from that sheet is printed,
2236  // this page can show a different sheet)
2237  nPage = pPrintFuncCache->GetTabStart( aTargetRange.aStart.Tab() );
2238  aArea = pDev->PixelToLogic( tools::Rectangle( 0,0,0,0 ) );
2239  }
2240  else
2241  {
2242  pPrintFuncCache->InitLocations( aMark, pDev ); // does nothing if already initialized
2243 
2244  ScPrintPageLocation aLocation;
2245  if ( pPrintFuncCache->FindLocation( aTargetRange.aStart, aLocation ) )
2246  {
2247  nPage = aLocation.nPage;
2248 
2249  // get the rectangle of the page's cell range in 1/100th mm
2250  ScRange aLocRange = aLocation.aCellRange;
2251  tools::Rectangle aLocationMM = rDoc.GetMMRect(
2252  aLocRange.aStart.Col(), aLocRange.aStart.Row(),
2253  aLocRange.aEnd.Col(), aLocRange.aEnd.Row(),
2254  aLocRange.aStart.Tab() );
2255  tools::Rectangle aLocationPixel = aLocation.aRectangle;
2256 
2257  // Scale and move the target rectangle from aLocationMM to aLocationPixel,
2258  // to get the target rectangle in pixels.
2259  assert(aLocationPixel.GetWidth() != 0 && aLocationPixel.GetHeight() != 0);
2260 
2261  Fraction aScaleX( aLocationPixel.GetWidth(), aLocationMM.GetWidth() );
2262  Fraction aScaleY( aLocationPixel.GetHeight(), aLocationMM.GetHeight() );
2263 
2264  long nX1 = aLocationPixel.Left() + static_cast<long>( Fraction( aTargetRect.Left() - aLocationMM.Left(), 1 ) * aScaleX );
2265  long nX2 = aLocationPixel.Left() + static_cast<long>( Fraction( aTargetRect.Right() - aLocationMM.Left(), 1 ) * aScaleX );
2266  long nY1 = aLocationPixel.Top() + static_cast<long>( Fraction( aTargetRect.Top() - aLocationMM.Top(), 1 ) * aScaleY );
2267  long nY2 = aLocationPixel.Top() + static_cast<long>( Fraction( aTargetRect.Bottom() - aLocationMM.Top(), 1 ) * aScaleY );
2268 
2269  if ( nX1 > aLocationPixel.Right() ) nX1 = aLocationPixel.Right();
2270  if ( nX2 > aLocationPixel.Right() ) nX2 = aLocationPixel.Right();
2271  if ( nY1 > aLocationPixel.Bottom() ) nY1 = aLocationPixel.Bottom();
2272  if ( nY2 > aLocationPixel.Bottom() ) nY2 = aLocationPixel.Bottom();
2273 
2274  // The link target area is interpreted using the device's MapMode at
2275  // the time of the CreateDest call, so PixelToLogic can be used here,
2276  // regardless of the MapMode that is actually selected.
2277  aArea = pDev->PixelToLogic( tools::Rectangle( nX1, nY1, nX2, nY2 ) );
2278  }
2279  }
2280 
2281  if ( nPage >= 0 )
2282  pPDFData->SetLinkDest( rBookmark.nLinkId, pPDFData->CreateDest( aArea, nPage ) );
2283  }
2284  }
2285  else
2286  {
2287  // external link, use as-is
2288  pPDFData->SetLinkURL( rBookmark.nLinkId, aBookmark );
2289  }
2290  }
2291  rBookmarks.clear();
2292  }
2293 }
2294 
2295 // XLinkTargetSupplier
2296 
2297 uno::Reference<container::XNameAccess> SAL_CALL ScModelObj::getLinks()
2298 {
2299  SolarMutexGuard aGuard;
2300  if (pDocShell)
2301  return new ScLinkTargetTypesObj(pDocShell);
2302  return nullptr;
2303 }
2304 
2305 // XActionLockable
2306 
2308 {
2309  SolarMutexGuard aGuard;
2310  bool bLocked = false;
2311  if (pDocShell)
2312  bLocked = ( pDocShell->GetLockCount() != 0 );
2313  return bLocked;
2314 }
2315 
2317 {
2318  SolarMutexGuard aGuard;
2319  if (pDocShell)
2321 }
2322 
2324 {
2325  SolarMutexGuard aGuard;
2326  if (pDocShell)
2328 }
2329 
2330 void SAL_CALL ScModelObj::setActionLocks( sal_Int16 nLock )
2331 {
2332  SolarMutexGuard aGuard;
2333  if (pDocShell)
2334  pDocShell->SetLockCount(nLock);
2335 }
2336 
2337 sal_Int16 SAL_CALL ScModelObj::resetActionLocks()
2338 {
2339  SolarMutexGuard aGuard;
2340  sal_uInt16 nRet = 0;
2341  if (pDocShell)
2342  {
2343  nRet = pDocShell->GetLockCount();
2344  pDocShell->SetLockCount(0);
2345  }
2346  return nRet;
2347 }
2348 
2350 {
2351  SolarMutexGuard aGuard;
2353  if (pDocShell)
2354  pDocShell->LockPaint();
2355 }
2356 
2358 {
2359  SolarMutexGuard aGuard;
2360  if (hasControllersLocked())
2361  {
2363  if (pDocShell)
2365  }
2366 }
2367 
2368 // XCalculate
2369 
2370 void SAL_CALL ScModelObj::calculate()
2371 {
2372  SolarMutexGuard aGuard;
2373  if (pDocShell)
2374  {
2375  comphelper::ProfileZone aZone("calculate");
2376  pDocShell->DoRecalc(true);
2377  }
2378  else
2379  {
2380  OSL_FAIL("no DocShell");
2381  }
2382 }
2383 
2385 {
2386  SolarMutexGuard aGuard;
2387  if (pDocShell)
2388  {
2389  comphelper::ProfileZone aZone("calculateAll");
2391  }
2392  else
2393  {
2394  OSL_FAIL("no DocShell");
2395  }
2396 }
2397 
2399 {
2400  SolarMutexGuard aGuard;
2401  if (pDocShell)
2402  return pDocShell->GetDocument().GetAutoCalc();
2403 
2404  OSL_FAIL("no DocShell");
2405  return false;
2406 }
2407 
2409 {
2410  bool bEnabled(bEnabledIn);
2411  SolarMutexGuard aGuard;
2412  if (pDocShell)
2413  {
2414  ScDocument& rDoc = pDocShell->GetDocument();
2415  if ( rDoc.GetAutoCalc() != bEnabled )
2416  {
2417  rDoc.SetAutoCalc( bEnabled );
2419  }
2420  }
2421  else
2422  {
2423  OSL_FAIL("no DocShell");
2424  }
2425 }
2426 
2427 // XProtectable
2428 
2429 void SAL_CALL ScModelObj::protect( const OUString& aPassword )
2430 {
2431  SolarMutexGuard aGuard;
2432  // #i108245# if already protected, don't change anything
2434  {
2435  pDocShell->GetDocFunc().Protect( TABLEID_DOC, aPassword );
2436  }
2437 }
2438 
2439 void SAL_CALL ScModelObj::unprotect( const OUString& aPassword )
2440 {
2441  SolarMutexGuard aGuard;
2442  if (pDocShell)
2443  {
2444  bool bDone = pDocShell->GetDocFunc().Unprotect( TABLEID_DOC, aPassword, true );
2445  if (!bDone)
2446  throw lang::IllegalArgumentException();
2447  }
2448 }
2449 
2451 {
2452  SolarMutexGuard aGuard;
2453  if (pDocShell)
2454  return pDocShell->GetDocument().IsDocProtected();
2455 
2456  OSL_FAIL("no DocShell");
2457  return false;
2458 }
2459 
2460 // XDrawPagesSupplier
2461 
2462 uno::Reference<drawing::XDrawPages> SAL_CALL ScModelObj::getDrawPages()
2463 {
2464  SolarMutexGuard aGuard;
2465  if (pDocShell)
2466  return new ScDrawPagesObj(pDocShell);
2467 
2468  OSL_FAIL("no DocShell");
2469  return nullptr;
2470 }
2471 
2472 // XGoalSeek
2473 
2474 sheet::GoalResult SAL_CALL ScModelObj::seekGoal(
2475  const table::CellAddress& aFormulaPosition,
2476  const table::CellAddress& aVariablePosition,
2477  const OUString& aGoalValue )
2478 {
2479  SolarMutexGuard aGuard;
2480  sheet::GoalResult aResult;
2481  aResult.Divergence = DBL_MAX; // not found
2482  if (pDocShell)
2483  {
2485  ScDocument& rDoc = pDocShell->GetDocument();
2486  double fValue = 0.0;
2487  bool bFound = rDoc.Solver(
2488  static_cast<SCCOL>(aFormulaPosition.Column), static_cast<SCROW>(aFormulaPosition.Row), aFormulaPosition.Sheet,
2489  static_cast<SCCOL>(aVariablePosition.Column), static_cast<SCROW>(aVariablePosition.Row), aVariablePosition.Sheet,
2490  aGoalValue, fValue );
2491  aResult.Result = fValue;
2492  if (bFound)
2493  aResult.Divergence = 0.0;
2494  }
2495  return aResult;
2496 }
2497 
2498 // XConsolidatable
2499 
2500 uno::Reference<sheet::XConsolidationDescriptor> SAL_CALL ScModelObj::createConsolidationDescriptor(
2501  sal_Bool bEmpty )
2502 {
2503  SolarMutexGuard aGuard;
2505  if ( pDocShell && !bEmpty )
2506  {
2507  ScDocument& rDoc = pDocShell->GetDocument();
2508  const ScConsolidateParam* pParam = rDoc.GetConsolidateDlgData();
2509  if (pParam)
2510  pNew->SetParam( *pParam );
2511  }
2512  return pNew;
2513 }
2514 
2516  const uno::Reference<sheet::XConsolidationDescriptor>& xDescriptor )
2517 {
2518  SolarMutexGuard aGuard;
2519  // in theory, this could also be a different object, so use only
2520  // public XConsolidationDescriptor interface to copy the data into
2521  // ScConsolidationDescriptor object
2523 
2525  xImpl->setFunction( xDescriptor->getFunction() );
2526  xImpl->setSources( xDescriptor->getSources() );
2527  xImpl->setStartOutputPosition( xDescriptor->getStartOutputPosition() );
2528  xImpl->setUseColumnHeaders( xDescriptor->getUseColumnHeaders() );
2529  xImpl->setUseRowHeaders( xDescriptor->getUseRowHeaders() );
2530  xImpl->setInsertLinks( xDescriptor->getInsertLinks() );
2531 
2532  if (pDocShell)
2533  {
2534  const ScConsolidateParam& rParam = xImpl->GetParam();
2535  pDocShell->DoConsolidate( rParam );
2536  pDocShell->GetDocument().SetConsolidateDlgData( std::unique_ptr<ScConsolidateParam>(new ScConsolidateParam(rParam)) );
2537  }
2538 }
2539 
2540 // XDocumentAuditing
2541 
2543 {
2544  SolarMutexGuard aGuard;
2545  if (pDocShell)
2547 }
2548 
2549 // XViewDataSupplier
2550 uno::Reference< container::XIndexAccess > SAL_CALL ScModelObj::getViewData( )
2551 {
2552  uno::Reference < container::XIndexAccess > xRet( SfxBaseModel::getViewData() );
2553 
2554  if( !xRet.is() )
2555  {
2556  SolarMutexGuard aGuard;
2557  if (pDocShell && pDocShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED)
2558  {
2559  uno::Reference < container::XIndexContainer > xCont = document::IndexedPropertyValues::create( ::comphelper::getProcessComponentContext() );
2560  xRet.set( xCont, uno::UNO_QUERY_THROW );
2561 
2562  uno::Sequence< beans::PropertyValue > aSeq;
2563  aSeq.realloc(3);
2564  OUString sName;
2566  OUString sOUName(sName);
2567  aSeq[0].Name = SC_ACTIVETABLE;
2568  aSeq[0].Value <<= sOUName;
2569  SCCOL nPosLeft = pDocShell->GetDocument().GetPosLeft();
2570  aSeq[1].Name = SC_POSITIONLEFT;
2571  aSeq[1].Value <<= nPosLeft;
2572  SCROW nPosTop = pDocShell->GetDocument().GetPosTop();
2573  aSeq[2].Name = SC_POSITIONTOP;
2574  aSeq[2].Value <<= nPosTop;
2575  xCont->insertByIndex( 0, uno::makeAny( aSeq ) );
2576  }
2577  }
2578 
2579  return xRet;
2580 }
2581 
2582 // XPropertySet (Doc-Options)
2584 
2585 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScModelObj::getPropertySetInfo()
2586 {
2587  SolarMutexGuard aGuard;
2588  static uno::Reference<beans::XPropertySetInfo> aRef(
2590  return aRef;
2591 }
2592 
2594  const OUString& aPropertyName, const uno::Any& aValue )
2595 {
2596  SolarMutexGuard aGuard;
2597 
2598  if (pDocShell)
2599  {
2600  ScDocument& rDoc = pDocShell->GetDocument();
2601  const ScDocOptions& rOldOpt = rDoc.GetDocOptions();
2602  ScDocOptions aNewOpt = rOldOpt;
2603  // Don't recalculate while loading XML, when the formula text is stored
2604  // Recalculation after loading is handled separately.
2605  bool bHardRecalc = !rDoc.IsImportingXML();
2606 
2607  bool bOpt = ScDocOptionsHelper::setPropertyValue( aNewOpt, aPropSet.getPropertyMap(), aPropertyName, aValue );
2608  if (bOpt)
2609  {
2610  // done...
2611  if ( aPropertyName == SC_UNO_IGNORECASE ||
2612  aPropertyName == SC_UNONAME_REGEXP ||
2613  aPropertyName == SC_UNONAME_WILDCARDS ||
2614  aPropertyName == SC_UNO_LOOKUPLABELS )
2615  bHardRecalc = false;
2616  }
2617  else if ( aPropertyName == SC_UNONAME_CLOCAL )
2618  {
2619  lang::Locale aLocale;
2620  if ( aValue >>= aLocale )
2621  {
2622  LanguageType eLatin, eCjk, eCtl;
2623  rDoc.GetLanguage( eLatin, eCjk, eCtl );
2624  eLatin = ScUnoConversion::GetLanguage(aLocale);
2625  rDoc.SetLanguage( eLatin, eCjk, eCtl );
2626  }
2627  }
2628  else if ( aPropertyName == SC_UNO_CODENAME )
2629  {
2630  OUString sCodeName;
2631  if ( aValue >>= sCodeName )
2632  rDoc.SetCodeName( sCodeName );
2633  }
2634  else if ( aPropertyName == SC_UNO_CJK_CLOCAL )
2635  {
2636  lang::Locale aLocale;
2637  if ( aValue >>= aLocale )
2638  {
2639  LanguageType eLatin, eCjk, eCtl;
2640  rDoc.GetLanguage( eLatin, eCjk, eCtl );
2641  eCjk = ScUnoConversion::GetLanguage(aLocale);
2642  rDoc.SetLanguage( eLatin, eCjk, eCtl );
2643  }
2644  }
2645  else if ( aPropertyName == SC_UNO_CTL_CLOCAL )
2646  {
2647  lang::Locale aLocale;
2648  if ( aValue >>= aLocale )
2649  {
2650  LanguageType eLatin, eCjk, eCtl;
2651  rDoc.GetLanguage( eLatin, eCjk, eCtl );
2652  eCtl = ScUnoConversion::GetLanguage(aLocale);
2653  rDoc.SetLanguage( eLatin, eCjk, eCtl );
2654  }
2655  }
2656  else if ( aPropertyName == SC_UNO_APPLYFMDES )
2657  {
2658  // model is created if not there
2659  ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
2661 
2662  SfxBindings* pBindings = pDocShell->GetViewBindings();
2663  if (pBindings)
2664  pBindings->Invalidate( SID_FM_OPEN_READONLY );
2665  }
2666  else if ( aPropertyName == SC_UNO_AUTOCONTFOC )
2667  {
2668  // model is created if not there
2669  ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
2671 
2672  SfxBindings* pBindings = pDocShell->GetViewBindings();
2673  if (pBindings)
2674  pBindings->Invalidate( SID_FM_AUTOCONTROLFOCUS );
2675  }
2676  else if ( aPropertyName == SC_UNO_ISLOADED )
2677  {
2679  }
2680  else if ( aPropertyName == SC_UNO_ISUNDOENABLED )
2681  {
2682  bool bUndoEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue );
2683  rDoc.EnableUndo( bUndoEnabled );
2685  bUndoEnabled
2686  ? officecfg::Office::Common::Undo::Steps::get() : 0);
2687  }
2688  else if ( aPropertyName == SC_UNO_RECORDCHANGES )
2689  {
2690  bool bRecordChangesEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue );
2691 
2692  bool bChangeAllowed = true;
2693  if (!bRecordChangesEnabled)
2694  bChangeAllowed = !pDocShell->HasChangeRecordProtection();
2695 
2696  if (bChangeAllowed)
2697  pDocShell->SetChangeRecording(bRecordChangesEnabled);
2698  }
2699  else if ( aPropertyName == SC_UNO_ISADJUSTHEIGHTENABLED )
2700  {
2701  if( ScUnoHelpFunctions::GetBoolFromAny( aValue ) )
2702  rDoc.UnlockAdjustHeight();
2703  else
2704  rDoc.LockAdjustHeight();
2705  }
2706  else if ( aPropertyName == SC_UNO_ISEXECUTELINKENABLED )
2707  {
2709  }
2710  else if ( aPropertyName == SC_UNO_ISCHANGEREADONLYENABLED )
2711  {
2713  }
2714  else if ( aPropertyName == "BuildId" )
2715  {
2716  aValue >>= maBuildId;
2717  }
2718  else if ( aPropertyName == "SavedObject" ) // set from chart after saving
2719  {
2720  OUString aObjName;
2721  aValue >>= aObjName;
2722  if ( !aObjName.isEmpty() )
2723  rDoc.RestoreChartListener( aObjName );
2724  }
2725  else if ( aPropertyName == SC_UNO_INTEROPGRABBAG )
2726  {
2727  setGrabBagItem(aValue);
2728  }
2729 
2730  if ( aNewOpt != rOldOpt )
2731  {
2732  rDoc.SetDocOptions( aNewOpt );
2734  if ( bHardRecalc )
2737  }
2738  }
2739 }
2740 
2741 uno::Any SAL_CALL ScModelObj::getPropertyValue( const OUString& aPropertyName )
2742 {
2743  SolarMutexGuard aGuard;
2744  uno::Any aRet;
2745 
2746  if (pDocShell)
2747  {
2748  ScDocument& rDoc = pDocShell->GetDocument();
2749  const ScDocOptions& rOpt = rDoc.GetDocOptions();
2750  aRet = ScDocOptionsHelper::getPropertyValue( rOpt, aPropSet.getPropertyMap(), aPropertyName );
2751  if ( aRet.hasValue() )
2752  {
2753  // done...
2754  }
2755  else if ( aPropertyName == SC_UNONAME_CLOCAL )
2756  {
2757  LanguageType eLatin, eCjk, eCtl;
2758  rDoc.GetLanguage( eLatin, eCjk, eCtl );
2759 
2760  lang::Locale aLocale;
2761  ScUnoConversion::FillLocale( aLocale, eLatin );
2762  aRet <<= aLocale;
2763  }
2764  else if ( aPropertyName == SC_UNO_CODENAME )
2765  {
2766  aRet <<= rDoc.GetCodeName();
2767  }
2768 
2769  else if ( aPropertyName == SC_UNO_CJK_CLOCAL )
2770  {
2771  LanguageType eLatin, eCjk, eCtl;
2772  rDoc.GetLanguage( eLatin, eCjk, eCtl );
2773 
2774  lang::Locale aLocale;
2775  ScUnoConversion::FillLocale( aLocale, eCjk );
2776  aRet <<= aLocale;
2777  }
2778  else if ( aPropertyName == SC_UNO_CTL_CLOCAL )
2779  {
2780  LanguageType eLatin, eCjk, eCtl;
2781  rDoc.GetLanguage( eLatin, eCjk, eCtl );
2782 
2783  lang::Locale aLocale;
2784  ScUnoConversion::FillLocale( aLocale, eCtl );
2785  aRet <<= aLocale;
2786  }
2787  else if ( aPropertyName == SC_UNO_NAMEDRANGES )
2788  {
2789  aRet <<= uno::Reference<sheet::XNamedRanges>(new ScGlobalNamedRangesObj( pDocShell ));
2790  }
2791  else if ( aPropertyName == SC_UNO_DATABASERNG )
2792  {
2793  aRet <<= uno::Reference<sheet::XDatabaseRanges>(new ScDatabaseRangesObj( pDocShell ));
2794  }
2795  else if ( aPropertyName == SC_UNO_UNNAMEDDBRNG )
2796  {
2797  aRet <<= uno::Reference<sheet::XUnnamedDatabaseRanges>(new ScUnnamedDatabaseRangesObj(pDocShell));
2798  }
2799  else if ( aPropertyName == SC_UNO_COLLABELRNG )
2800  {
2801  aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, true ));
2802  }
2803  else if ( aPropertyName == SC_UNO_ROWLABELRNG )
2804  {
2805  aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, false ));
2806  }
2807  else if ( aPropertyName == SC_UNO_AREALINKS )
2808  {
2809  aRet <<= uno::Reference<sheet::XAreaLinks>(new ScAreaLinksObj( pDocShell ));
2810  }
2811  else if ( aPropertyName == SC_UNO_DDELINKS )
2812  {
2813  aRet <<= uno::Reference<container::XNameAccess>(new ScDDELinksObj( pDocShell ));
2814  }
2815  else if ( aPropertyName == SC_UNO_EXTERNALDOCLINKS )
2816  {
2817  aRet <<= uno::Reference<sheet::XExternalDocLinks>(new ScExternalDocLinksObj(pDocShell));
2818  }
2819  else if ( aPropertyName == SC_UNO_SHEETLINKS )
2820  {
2821  aRet <<= uno::Reference<container::XNameAccess>(new ScSheetLinksObj( pDocShell ));
2822  }
2823  else if ( aPropertyName == SC_UNO_APPLYFMDES )
2824  {
2825  // default for no model is TRUE
2826  ScDrawLayer* pModel = rDoc.GetDrawLayer();
2827  bool bOpenInDesign = pModel == nullptr || pModel->GetOpenInDesignMode();
2828  aRet <<= bOpenInDesign;
2829  }
2830  else if ( aPropertyName == SC_UNO_AUTOCONTFOC )
2831  {
2832  // default for no model is FALSE
2833  ScDrawLayer* pModel = rDoc.GetDrawLayer();
2834  bool bAutoControlFocus = pModel && pModel->GetAutoControlFocus();
2835  aRet <<= bAutoControlFocus;
2836  }
2837  else if ( aPropertyName == SC_UNO_FORBIDDEN )
2838  {
2839  aRet <<= uno::Reference<i18n::XForbiddenCharacters>(new ScForbiddenCharsObj( pDocShell ));
2840  }
2841  else if ( aPropertyName == SC_UNO_HASDRAWPAGES )
2842  {
2843  aRet <<= (pDocShell->GetDocument().GetDrawLayer() != nullptr);
2844  }
2845  else if ( aPropertyName == SC_UNO_BASICLIBRARIES )
2846  {
2847  aRet <<= pDocShell->GetBasicContainer();
2848  }
2849  else if ( aPropertyName == SC_UNO_DIALOGLIBRARIES )
2850  {
2851  aRet <<= pDocShell->GetDialogContainer();
2852  }
2853  else if ( aPropertyName == SC_UNO_VBAGLOBNAME )
2854  {
2855  /* #i111553# This property provides the name of the constant that
2856  will be used to store this model in the global Basic manager.
2857  That constant will be equivalent to 'ThisComponent' but for
2858  each application, so e.g. a 'ThisExcelDoc' and a 'ThisWordDoc'
2859  constant can co-exist, as required by VBA. */
2860  aRet <<= OUString( "ThisExcelDoc" );
2861  }
2862  else if ( aPropertyName == SC_UNO_RUNTIMEUID )
2863  {
2864  aRet <<= getRuntimeUID();
2865  }
2866  else if ( aPropertyName == SC_UNO_HASVALIDSIGNATURES )
2867  {
2868  aRet <<= hasValidSignatures();
2869  }
2870  else if ( aPropertyName == SC_UNO_ISLOADED )
2871  {
2872  aRet <<= !pDocShell->IsEmpty();
2873  }
2874  else if ( aPropertyName == SC_UNO_ISUNDOENABLED )
2875  {
2876  aRet <<= rDoc.IsUndoEnabled();
2877  }
2878  else if ( aPropertyName == SC_UNO_RECORDCHANGES )
2879  {
2880  aRet <<= pDocShell->IsChangeRecording();
2881  }
2882  else if ( aPropertyName == SC_UNO_ISRECORDCHANGESPROTECTED )
2883  {
2885  }
2886  else if ( aPropertyName == SC_UNO_ISADJUSTHEIGHTENABLED )
2887  {
2888  aRet <<= !( rDoc.IsAdjustHeightLocked() );
2889  }
2890  else if ( aPropertyName == SC_UNO_ISEXECUTELINKENABLED )
2891  {
2892  aRet <<= rDoc.IsExecuteLinkEnabled();
2893  }
2894  else if ( aPropertyName == SC_UNO_ISCHANGEREADONLYENABLED )
2895  {
2896  aRet <<= rDoc.IsChangeReadOnlyEnabled();
2897  }
2898  else if ( aPropertyName == SC_UNO_REFERENCEDEVICE )
2899  {
2900  VCLXDevice* pXDev = new VCLXDevice();
2901  pXDev->SetOutputDevice( rDoc.GetRefDevice() );
2902  aRet <<= uno::Reference< awt::XDevice >( pXDev );
2903  }
2904  else if ( aPropertyName == "BuildId" )
2905  {
2906  aRet <<= maBuildId;
2907  }
2908  else if ( aPropertyName == "InternalDocument" )
2909  {
2910  aRet <<= (pDocShell->GetCreateMode() == SfxObjectCreateMode::INTERNAL);
2911  }
2912  else if ( aPropertyName == SC_UNO_INTEROPGRABBAG )
2913  {
2914  getGrabBagItem(aRet);
2915  }
2916  }
2917 
2918  return aRet;
2919 }
2920 
2922 
2923 // XMultiServiceFactory
2924 
2925 css::uno::Reference<css::uno::XInterface> ScModelObj::create(
2926  OUString const & aServiceSpecifier,
2927  css::uno::Sequence<css::uno::Any> const * arguments)
2928 {
2930 
2931  uno::Reference<uno::XInterface> xRet;
2933  if ( nType != ServiceType::INVALID )
2934  {
2935  // drawing layer tables must be kept as long as the model is alive
2936  // return stored instance if already set
2937  switch ( nType )
2938  {
2939  case ServiceType::GRADTAB: xRet.set(xDrawGradTab); break;
2940  case ServiceType::HATCHTAB: xRet.set(xDrawHatchTab); break;
2941  case ServiceType::BITMAPTAB: xRet.set(xDrawBitmapTab); break;
2942  case ServiceType::TRGRADTAB: xRet.set(xDrawTrGradTab); break;
2943  case ServiceType::MARKERTAB: xRet.set(xDrawMarkerTab); break;
2944  case ServiceType::DASHTAB: xRet.set(xDrawDashTab); break;
2945  case ServiceType::CHDATAPROV: xRet.set(xChartDataProv); break;
2946  case ServiceType::VBAOBJECTPROVIDER: xRet.set(xObjProvider); break;
2947  default: break;
2948  }
2949 
2950  // #i64497# If a chart is in a temporary document during clipboard paste,
2951  // there should be no data provider, so that own data is used
2952  bool bCreate =
2953  ( nType != ServiceType::CHDATAPROV ||
2954  ( pDocShell->GetCreateMode() != SfxObjectCreateMode::INTERNAL ));
2955  // this should never happen, i.e. the temporary document should never be
2956  // loaded, because this unlinks the data
2957  assert(bCreate);
2958 
2959  if ( !xRet.is() && bCreate )
2960  {
2961  xRet.set(ScServiceProvider::MakeInstance( nType, pDocShell ));
2962 
2963  // store created instance
2964  switch ( nType )
2965  {
2966  case ServiceType::GRADTAB: xDrawGradTab.set(xRet); break;
2967  case ServiceType::HATCHTAB: xDrawHatchTab.set(xRet); break;
2968  case ServiceType::BITMAPTAB: xDrawBitmapTab.set(xRet); break;
2969  case ServiceType::TRGRADTAB: xDrawTrGradTab.set(xRet); break;
2970  case ServiceType::MARKERTAB: xDrawMarkerTab.set(xRet); break;
2971  case ServiceType::DASHTAB: xDrawDashTab.set(xRet); break;
2972  case ServiceType::CHDATAPROV: xChartDataProv.set(xRet); break;
2973  case ServiceType::VBAOBJECTPROVIDER: xObjProvider.set(xRet); break;
2974  default: break;
2975  }
2976  }
2977  }
2978  else
2979  {
2980  // we offload everything we don't know to SvxFmMSFactory,
2981  // it'll throw exception if this isn't okay ...
2982 
2983  try
2984  {
2985  xRet = arguments == nullptr
2986  ? SvxFmMSFactory::createInstance(aServiceSpecifier)
2988  aServiceSpecifier, *arguments);
2989  // extra block to force deletion of the temporary before ScShapeObj ctor (setDelegator)
2990  }
2991  catch ( lang::ServiceNotRegisteredException & )
2992  {
2993  }
2994 
2995  // if the drawing factory created a shape, a ScShapeObj has to be used
2996  // to support own properties like ImageMap:
2997 
2998  uno::Reference<drawing::XShape> xShape( xRet, uno::UNO_QUERY );
2999  if ( xShape.is() )
3000  {
3001  xRet.clear(); // for aggregation, xShape must be the object's only ref
3002  new ScShapeObj( xShape ); // aggregates object and modifies xShape
3003  xRet.set(xShape);
3004  }
3005  }
3006  return xRet;
3007 }
3008 
3009 uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstance(
3010  const OUString& aServiceSpecifier )
3011 {
3012  SolarMutexGuard aGuard;
3013  return create(aServiceSpecifier, nullptr);
3014 }
3015 
3016 uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstanceWithArguments(
3017  const OUString& ServiceSpecifier,
3018  const uno::Sequence<uno::Any>& aArgs )
3019 {
3021 
3022  SolarMutexGuard aGuard;
3023  uno::Reference<uno::XInterface> xInt(create(ServiceSpecifier, &aArgs));
3024 
3025  if ( aArgs.hasElements() )
3026  {
3027  // used only for cell value binding so far - it can be initialized after creating
3028 
3029  uno::Reference<lang::XInitialization> xInit( xInt, uno::UNO_QUERY );
3030  if ( xInit.is() )
3031  xInit->initialize( aArgs );
3032  }
3033 
3034  return xInt;
3035 }
3036 
3037 uno::Sequence<OUString> SAL_CALL ScModelObj::getAvailableServiceNames()
3038 {
3039  SolarMutexGuard aGuard;
3040 
3043 }
3044 
3045 // XServiceInfo
3047 {
3048  return "ScModelObj";
3049  /* // Matching the .component information:
3050  return OUString( "com.sun.star.comp.Calc.SpreadsheetDocument" );
3051  */
3052 }
3053 
3054 sal_Bool SAL_CALL ScModelObj::supportsService( const OUString& rServiceName )
3055 {
3056  return cppu::supportsService(this, rServiceName);
3057 }
3058 
3059 uno::Sequence<OUString> SAL_CALL ScModelObj::getSupportedServiceNames()
3060 {
3062 }
3063 
3064 // XUnoTunnel
3065 
3066 sal_Int64 SAL_CALL ScModelObj::getSomething(
3067  const uno::Sequence<sal_Int8 >& rId )
3068 {
3069  if ( isUnoTunnelId<ScModelObj>(rId) )
3070  {
3071  return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
3072  }
3073 
3074  if ( isUnoTunnelId<SfxObjectShell>(rId) )
3075  {
3076  return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell ));
3077  }
3078 
3079  // aggregated number formats supplier has XUnoTunnel, too
3080  // interface from aggregated object must be obtained via queryAggregation
3081 
3082  sal_Int64 nRet = SfxBaseModel::getSomething( rId );
3083  if ( nRet )
3084  return nRet;
3085 
3086  if ( GetFormatter().is() )
3087  {
3088  const uno::Type& rTunnelType = cppu::UnoType<lang::XUnoTunnel>::get();
3089  uno::Any aNumTunnel(xNumberAgg->queryAggregation(rTunnelType));
3090  if(auto xTunnelAgg = o3tl::tryAccess<uno::Reference<lang::XUnoTunnel>>(
3091  aNumTunnel))
3092  {
3093  return (*xTunnelAgg)->getSomething( rId );
3094  }
3095  }
3096 
3097  return 0;
3098 }
3099 
3100 namespace
3101 {
3102  class theScModelObjUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScModelObjUnoTunnelId> {};
3103 }
3104 
3105 const uno::Sequence<sal_Int8>& ScModelObj::getUnoTunnelId()
3106 {
3107  return theScModelObjUnoTunnelId::get().getSeq();
3108 }
3109 
3110 // XChangesNotifier
3111 
3112 void ScModelObj::addChangesListener( const uno::Reference< util::XChangesListener >& aListener )
3113 {
3114  SolarMutexGuard aGuard;
3115  maChangesListeners.addInterface( aListener );
3116 }
3117 
3118 void ScModelObj::removeChangesListener( const uno::Reference< util::XChangesListener >& aListener )
3119 {
3120  SolarMutexGuard aGuard;
3121  maChangesListeners.removeInterface( aListener );
3122 }
3123 
3125 {
3126  if ( maChangesListeners.getLength() > 0 )
3127  return true;
3128 
3129  // "change" event set in any sheet?
3131 }
3132 
3133 void ScModelObj::NotifyChanges( const OUString& rOperation, const ScRangeList& rRanges,
3134  const uno::Sequence< beans::PropertyValue >& rProperties )
3135 {
3136  if ( pDocShell && HasChangesListeners() )
3137  {
3138  util::ChangesEvent aEvent;
3139  aEvent.Source.set( static_cast< cppu::OWeakObject* >( this ) );
3140  aEvent.Base <<= aEvent.Source;
3141 
3142  size_t nRangeCount = rRanges.size();
3143  aEvent.Changes.realloc( static_cast< sal_Int32 >( nRangeCount ) );
3144  for ( size_t nIndex = 0; nIndex < nRangeCount; ++nIndex )
3145  {
3146  uno::Reference< table::XCellRange > xRangeObj;
3147 
3148  ScRange const & rRange = rRanges[ nIndex ];
3149  if ( rRange.aStart == rRange.aEnd )
3150  {
3151  xRangeObj.set( new ScCellObj( pDocShell, rRange.aStart ) );
3152  }
3153  else
3154  {
3155  xRangeObj.set( new ScCellRangeObj( pDocShell, rRange ) );
3156  }
3157 
3158  util::ElementChange& rChange = aEvent.Changes[ static_cast< sal_Int32 >( nIndex ) ];
3159  rChange.Accessor <<= rOperation;
3160  rChange.Element <<= rProperties;
3161  rChange.ReplacedElement <<= xRangeObj;
3162  }
3163 
3165  while ( aIter.hasMoreElements() )
3166  {
3167  try
3168  {
3169  static_cast< util::XChangesListener* >( aIter.next() )->changesOccurred( aEvent );
3170  }
3171  catch( uno::Exception& )
3172  {
3173  }
3174  }
3175  }
3176 
3177  // handle sheet events
3179  if ( rOperation == "cell-change" && pDocShell )
3180  {
3182  aMarkData.MarkFromRangeList( rRanges, false );
3183  ScDocument& rDoc = pDocShell->GetDocument();
3184  SCTAB nTabCount = rDoc.GetTableCount();
3185  for (const SCTAB& nTab : aMarkData)
3186  {
3187  if (nTab >= nTabCount)
3188  break;
3189  const ScSheetEvents* pEvents = rDoc.GetSheetEvents(nTab);
3190  if (pEvents)
3191  {
3192  const OUString* pScript = pEvents->GetScript(ScSheetEventId::CHANGE);
3193  if (pScript)
3194  {
3195  ScRangeList aTabRanges; // collect ranges on this sheet
3196  size_t nRangeCount = rRanges.size();
3197  for ( size_t nIndex = 0; nIndex < nRangeCount; ++nIndex )
3198  {
3199  ScRange const & rRange = rRanges[ nIndex ];
3200  if ( rRange.aStart.Tab() == nTab )
3201  aTabRanges.push_back( rRange );
3202  }
3203  size_t nTabRangeCount = aTabRanges.size();
3204  if ( nTabRangeCount > 0 )
3205  {
3206  uno::Reference<uno::XInterface> xTarget;
3207  if ( nTabRangeCount == 1 )
3208  {
3209  ScRange const & rRange = aTabRanges[ 0 ];
3210  if ( rRange.aStart == rRange.aEnd )
3211  xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellObj( pDocShell, rRange.aStart ) ) );
3212  else
3213  xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangeObj( pDocShell, rRange ) ) );
3214  }
3215  else
3216  xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangesObj( pDocShell, aTabRanges ) ) );
3217 
3218  uno::Sequence<uno::Any> aParams(1);
3219  aParams[0] <<= xTarget;
3220 
3221  uno::Any aRet;
3222  uno::Sequence<sal_Int16> aOutArgsIndex;
3223  uno::Sequence<uno::Any> aOutArgs;
3224 
3225  /*ErrCode eRet =*/ pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
3226  }
3227  }
3228  }
3229  }
3230  }
3231 }
3232 
3234 {
3235  if (pDocShell)
3236  {
3237  ScDocument& rDoc = pDocShell->GetDocument();
3238  // don't call events before the document is visible
3239  // (might also set a flag on SfxEventHintId::LoadFinished and only disable while loading)
3240  if ( rDoc.IsDocVisible() )
3241  {
3242  SCTAB nTabCount = rDoc.GetTableCount();
3243  for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
3244  {
3245  if (rDoc.HasCalcNotification(nTab))
3246  {
3247  if (const ScSheetEvents* pEvents = rDoc.GetSheetEvents( nTab ))
3248  {
3249  if (const OUString* pScript = pEvents->GetScript(ScSheetEventId::CALCULATE))
3250  {
3251  uno::Any aRet;
3252  uno::Sequence<uno::Any> aParams;
3253  uno::Sequence<sal_Int16> aOutArgsIndex;
3254  uno::Sequence<uno::Any> aOutArgs;
3255  pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
3256  }
3257  }
3258 
3259  try
3260  {
3261  uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
3262  uno::Sequence< uno::Any > aArgs( 1 );
3263  aArgs[ 0 ] <<= nTab;
3264  xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( ScSheetEventId::CALCULATE ), aArgs );
3265  }
3266  catch( uno::Exception& )
3267  {
3268  }
3269  }
3270  }
3271  }
3272  rDoc.ResetCalcNotifications();
3273  }
3274 }
3275 
3276 // XOpenCLSelection
3277 
3279 {
3281 }
3282 
3284 {
3285  if (ScCalcConfig::isOpenCLEnabled() == static_cast<bool>(bEnable))
3286  return;
3288  return;
3289 
3290  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
3291  officecfg::Office::Common::Misc::UseOpenCL::set(bEnable, batch);
3292  batch->commit();
3293 
3295  if (bEnable)
3296  aConfig.setOpenCLConfigToDefault();
3298 
3299 #if HAVE_FEATURE_OPENCL
3300  sc::FormulaGroupInterpreter::switchOpenCLDevice(OUString(), true);
3301 #endif
3302 
3303  ScDocument* pDoc = GetDocument();
3304  pDoc->CheckVectorizationState();
3305 
3306 }
3307 
3309 {
3311  aConfig.mbOpenCLAutoSelect = true;
3313  ScFormulaOptions aOptions = SC_MOD()->GetFormulaOptions();
3314  aOptions.SetCalcConfig(aConfig);
3315  SC_MOD()->SetFormulaOptions(aOptions);
3316 #if !HAVE_FEATURE_OPENCL
3317  (void) bForce;
3318 #else
3319  sc::FormulaGroupInterpreter::switchOpenCLDevice(OUString(), true, bForce);
3320 #endif
3321 }
3322 
3324 {
3326  aConfig.mbOpenCLAutoSelect = false;
3328  ScFormulaOptions aOptions = SC_MOD()->GetFormulaOptions();
3329  aOptions.SetCalcConfig(aConfig);
3330  SC_MOD()->SetFormulaOptions(aOptions);
3331 }
3332 
3333 void ScModelObj::selectOpenCLDevice( sal_Int32 nPlatform, sal_Int32 nDevice )
3334 {
3335  if(nPlatform < 0 || nDevice < 0)
3336  throw uno::RuntimeException();
3337 
3338 #if !HAVE_FEATURE_OPENCL
3339  throw uno::RuntimeException();
3340 #else
3341  std::vector<OpenCLPlatformInfo> aPlatformInfo;
3342  sc::FormulaGroupInterpreter::fillOpenCLInfo(aPlatformInfo);
3343  if(o3tl::make_unsigned(nPlatform) >= aPlatformInfo.size())
3344  throw uno::RuntimeException();
3345 
3346  if(o3tl::make_unsigned(nDevice) >= aPlatformInfo[nPlatform].maDevices.size())
3347  throw uno::RuntimeException();
3348 
3349  OUString aDeviceString = aPlatformInfo[nPlatform].maVendor + " " + aPlatformInfo[nPlatform].maDevices[nDevice].maName;
3350  sc::FormulaGroupInterpreter::switchOpenCLDevice(aDeviceString, false);
3351 #endif
3352 }
3353 
3355 {
3356 #if !HAVE_FEATURE_OPENCL
3357  return -1;
3358 #else
3359  sal_Int32 nPlatformId;
3360  sal_Int32 nDeviceId;
3361  sc::FormulaGroupInterpreter::getOpenCLDeviceInfo(nDeviceId, nPlatformId);
3362  return nPlatformId;
3363 #endif
3364 }
3365 
3367 {
3368 #if !HAVE_FEATURE_OPENCL
3369  return -1;
3370 #else
3371  sal_Int32 nPlatformId;
3372  sal_Int32 nDeviceId;
3373  sc::FormulaGroupInterpreter::getOpenCLDeviceInfo(nDeviceId, nPlatformId);
3374  return nDeviceId;
3375 #endif
3376 }
3377 
3378 uno::Sequence< sheet::opencl::OpenCLPlatform > ScModelObj::getOpenCLPlatforms()
3379 {
3380 #if !HAVE_FEATURE_OPENCL
3381  return uno::Sequence<sheet::opencl::OpenCLPlatform>();
3382 #else
3383  std::vector<OpenCLPlatformInfo> aPlatformInfo;
3384  sc::FormulaGroupInterpreter::fillOpenCLInfo(aPlatformInfo);
3385 
3386  uno::Sequence<sheet::opencl::OpenCLPlatform> aRet(aPlatformInfo.size());
3387  for(size_t i = 0; i < aPlatformInfo.size(); ++i)
3388  {
3389  aRet[i].Name = aPlatformInfo[i].maName;
3390  aRet[i].Vendor = aPlatformInfo[i].maVendor;
3391 
3392  aRet[i].Devices.realloc(aPlatformInfo[i].maDevices.size());
3393  for(size_t j = 0; j < aPlatformInfo[i].maDevices.size(); ++j)
3394  {
3395  const OpenCLDeviceInfo& rDevice = aPlatformInfo[i].maDevices[j];
3396  aRet[i].Devices[j].Name = rDevice.maName;
3397  aRet[i].Devices[j].Vendor = rDevice.maVendor;
3398  aRet[i].Devices[j].Driver = rDevice.maDriver;
3399  }
3400  }
3401 
3402  return aRet;
3403 #endif
3404 }
3405 
3406 namespace {
3407 
3409 void setOpcodeSubsetTest(bool bFlag)
3410 {
3411  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
3412  officecfg::Office::Calc::Formula::Calculation::OpenCLSubsetOnly::set(bFlag, batch);
3413  batch->commit();
3414 }
3415 
3416 }
3417 
3419 {
3420  setOpcodeSubsetTest(true);
3421 }
3422 
3424 {
3425  setOpcodeSubsetTest(false);
3426 }
3427 
3429 {
3430  return officecfg::Office::Calc::Formula::Calculation::OpenCLSubsetOnly::get();
3431 }
3432 
3434 {
3435  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
3436  officecfg::Office::Calc::Formula::Calculation::OpenCLMinimumDataSize::set(number, batch);
3437  batch->commit();
3438 }
3439 
3441 {
3442  return officecfg::Office::Calc::Formula::Calculation::OpenCLMinimumDataSize::get();
3443 }
3444 
3446  pDocShell( pDocSh )
3447 {
3449 }
3450 
3452 {
3453  SolarMutexGuard g;
3454 
3455  if (pDocShell)
3457 }
3458 
3460 {
3461  // we don't care about update of references here
3462 
3463  if ( rHint.GetId() == SfxHintId::Dying )
3464  {
3465  pDocShell = nullptr; // became invalid
3466  }
3467 }
3468 
3469 uno::Reference<drawing::XDrawPage> ScDrawPagesObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
3470 {
3471  if (pDocShell)
3472  {
3473  ScDrawLayer* pDrawLayer = pDocShell->MakeDrawLayer();
3474  OSL_ENSURE(pDrawLayer,"Cannot create Draw-Layer");
3475  if ( pDrawLayer && nIndex >= 0 && nIndex < pDocShell->GetDocument().GetTableCount() )
3476  {
3477  SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nIndex));
3478  OSL_ENSURE(pPage,"Draw-Page not found");
3479  if (pPage)
3480  {
3481  return uno::Reference<drawing::XDrawPage> (pPage->getUnoPage(), uno::UNO_QUERY);
3482  }
3483  }
3484  }
3485  return nullptr;
3486 }
3487 
3488 // XDrawPages
3489 
3490 uno::Reference<drawing::XDrawPage> SAL_CALL ScDrawPagesObj::insertNewByIndex( sal_Int32 nPos )
3491 {
3492  SolarMutexGuard aGuard;
3493  uno::Reference<drawing::XDrawPage> xRet;
3494  if (pDocShell)
3495  {
3496  OUString aNewName;
3498  if ( pDocShell->GetDocFunc().InsertTable( static_cast<SCTAB>(nPos),
3499  aNewName, true, true ) )
3500  xRet.set(GetObjectByIndex_Impl( nPos ));
3501  }
3502  return xRet;
3503 }
3504 
3505 void SAL_CALL ScDrawPagesObj::remove( const uno::Reference<drawing::XDrawPage>& xPage )
3506 {
3507  SolarMutexGuard aGuard;
3508  SvxDrawPage* pImp = comphelper::getUnoTunnelImplementation<SvxDrawPage>( xPage );
3509  if ( pDocShell && pImp )
3510  {
3511  SdrPage* pPage = pImp->GetSdrPage();
3512  if (pPage)
3513  {
3514  SCTAB nPageNum = static_cast<SCTAB>(pPage->GetPageNum());
3515  pDocShell->GetDocFunc().DeleteTable( nPageNum, true );
3516  }
3517  }
3518 }
3519 
3520 // XIndexAccess
3521 
3522 sal_Int32 SAL_CALL ScDrawPagesObj::getCount()
3523 {
3524  SolarMutexGuard aGuard;
3525  if (pDocShell)
3526  return pDocShell->GetDocument().GetTableCount();
3527  return 0;
3528 }
3529 
3530 uno::Any SAL_CALL ScDrawPagesObj::getByIndex( sal_Int32 nIndex )
3531 {
3532  SolarMutexGuard aGuard;
3533  uno::Reference<drawing::XDrawPage> xPage(GetObjectByIndex_Impl(nIndex));
3534  if (!xPage.is())
3535  throw lang::IndexOutOfBoundsException();
3536 
3537  return uno::makeAny(xPage);
3538 }
3539 
3541 {
3542  SolarMutexGuard aGuard;
3544 }
3545 
3547 {
3548  SolarMutexGuard aGuard;
3549  return ( getCount() != 0 );
3550 }
3551 
3553  pDocShell( pDocSh )
3554 {
3556 }
3557 
3559 {
3560  SolarMutexGuard g;
3561 
3562  if (pDocShell)
3564 }
3565 
3567 {
3568  // we don't care about update of references here
3569 
3570  if ( rHint.GetId() == SfxHintId::Dying )
3571  {
3572  pDocShell = nullptr; // became invalid
3573  }
3574 }
3575 
3576 // XSpreadsheets
3577 
3579 {
3580  if ( pDocShell && nIndex >= 0 && nIndex < pDocShell->GetDocument().GetTableCount() )
3581  return new ScTableSheetObj( pDocShell, static_cast<SCTAB>(nIndex) );
3582 
3583  return nullptr;
3584 }
3585 
3587 {
3588  if (pDocShell)
3589  {
3590  SCTAB nIndex;
3591  if ( pDocShell->GetDocument().GetTable( aName, nIndex ) )
3592  return new ScTableSheetObj( pDocShell, nIndex );
3593  }
3594  return nullptr;
3595 }
3596 
3597 void SAL_CALL ScTableSheetsObj::insertNewByName( const OUString& aName, sal_Int16 nPosition )
3598 {
3599  SolarMutexGuard aGuard;
3600  bool bDone = false;
3601  if (pDocShell)
3602  {
3603  bDone = pDocShell->GetDocFunc().InsertTable( nPosition, aName, true, true );
3604  }
3605  if (!bDone)
3606  throw uno::RuntimeException(); // no other exceptions specified
3607 }
3608 
3609 void SAL_CALL ScTableSheetsObj::moveByName( const OUString& aName, sal_Int16 nDestination )
3610 {
3611  SolarMutexGuard aGuard;
3612  bool bDone = false;
3613  if (pDocShell)
3614  {
3615  SCTAB nSource;
3616  if ( pDocShell->GetDocument().GetTable( aName, nSource ) )
3617  bDone = pDocShell->MoveTable( nSource, nDestination, false, true );
3618  }
3619  if (!bDone)
3620  throw uno::RuntimeException(); // no other exceptions specified
3621 }
3622 
3623 void SAL_CALL ScTableSheetsObj::copyByName( const OUString& aName,
3624  const OUString& aCopy, sal_Int16 nDestination )
3625 {
3626  SolarMutexGuard aGuard;
3627  bool bDone = false;
3628  if (pDocShell)
3629  {
3630  SCTAB nSource;
3631  if ( pDocShell->GetDocument().GetTable( aName, nSource ) )
3632  {
3633  bDone = pDocShell->MoveTable( nSource, nDestination, true, true );
3634  if (bDone)
3635  {
3636  // #i92477# any index past the last sheet means "append" in MoveTable
3637  SCTAB nResultTab = static_cast<SCTAB>(nDestination);
3638  SCTAB nTabCount = pDocShell->GetDocument().GetTableCount(); // count after copying
3639  if (nResultTab >= nTabCount)
3640  nResultTab = nTabCount - 1;
3641 
3642  bDone = pDocShell->GetDocFunc().RenameTable( nResultTab, aCopy,
3643  true, true );
3644  }
3645  }
3646  }
3647  if (!bDone)
3648  throw uno::RuntimeException(); // no other exceptions specified
3649 }
3650 
3651 void SAL_CALL ScTableSheetsObj::insertByName( const OUString& aName, const uno::Any& aElement )
3652 {
3653  SolarMutexGuard aGuard;
3654  bool bDone = false;
3655  bool bIllArg = false;
3656 
3658 
3659  if ( pDocShell )
3660  {
3661  uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
3662  if ( xInterface.is() )
3663  {
3664  ScTableSheetObj* pSheetObj = comphelper::getUnoTunnelImplementation<ScTableSheetObj>( xInterface );
3665  if ( pSheetObj && !pSheetObj->GetDocShell() ) // not inserted yet?
3666  {
3667  ScDocument& rDoc = pDocShell->GetDocument();
3668  SCTAB nDummy;
3669  if ( rDoc.GetTable( aName, nDummy ) )
3670  {
3671  // name already exists
3672  throw container::ElementExistException();
3673  }
3674  SCTAB nPosition = rDoc.GetTableCount();
3675  bDone = pDocShell->GetDocFunc().InsertTable( nPosition, aName,
3676  true, true );
3677  if (bDone)
3678  pSheetObj->InitInsertSheet( pDocShell, nPosition );
3679  // set document and new range in the object
3680  }
3681  else
3682  bIllArg = true;
3683  }
3684  else
3685  bIllArg = true;
3686  }
3687 
3688  if (!bDone)
3689  {
3690  if (bIllArg)
3691  throw lang::IllegalArgumentException();
3692  else
3693  throw uno::RuntimeException(); // ElementExistException is handled above
3694  }
3695 }
3696 
3697 void SAL_CALL ScTableSheetsObj::replaceByName( const OUString& aName, const uno::Any& aElement )
3698 {
3699  SolarMutexGuard aGuard;
3700  bool bDone = false;
3701  bool bIllArg = false;
3702 
3704 
3705  if ( pDocShell )
3706  {
3707  uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
3708  if ( xInterface.is() )
3709  {
3710  ScTableSheetObj* pSheetObj = comphelper::getUnoTunnelImplementation<ScTableSheetObj>( xInterface );
3711  if ( pSheetObj && !pSheetObj->GetDocShell() ) // not inserted yet?
3712  {
3713  SCTAB nPosition;
3714  if ( !pDocShell->GetDocument().GetTable( aName, nPosition ) )
3715  {
3716  // not found
3717  throw container::NoSuchElementException();
3718  }
3719 
3720  if ( pDocShell->GetDocFunc().DeleteTable( nPosition, true ) )
3721  {
3722  // InsertTable can't really go wrong now
3723  bDone = pDocShell->GetDocFunc().InsertTable( nPosition, aName, true, true );
3724  if (bDone)
3725  pSheetObj->InitInsertSheet( pDocShell, nPosition );
3726  }
3727 
3728  }
3729  else
3730  bIllArg = true;
3731  }
3732  else
3733  bIllArg = true;
3734  }
3735 
3736  if (!bDone)
3737  {
3738  if (bIllArg)
3739  throw lang::IllegalArgumentException();
3740  else
3741  throw uno::RuntimeException(); // NoSuchElementException is handled above
3742  }
3743 }
3744 
3745 void SAL_CALL ScTableSheetsObj::removeByName( const OUString& aName )
3746 {
3747  SolarMutexGuard aGuard;
3748  bool bDone = false;
3749  if (pDocShell)
3750  {
3751  SCTAB nIndex;
3752  if ( !pDocShell->GetDocument().GetTable( aName, nIndex ) )
3753  throw container::NoSuchElementException(); // not found
3754  bDone = pDocShell->GetDocFunc().DeleteTable( nIndex, true );
3755  }
3756 
3757  if (!bDone)
3758  throw uno::RuntimeException(); // NoSuchElementException is handled above
3759 }
3760 
3762  const uno::Reference < sheet::XSpreadsheetDocument > & xDocSrc,
3763  const OUString& srcName, const sal_Int32 nDestPosition )
3764 {
3765  //pDocShell is the destination
3766  ScDocument& rDocDest = pDocShell->GetDocument();
3767 
3768  // Source document docShell
3769  if ( !xDocSrc.is() )
3770  throw uno::RuntimeException();
3771  ScModelObj* pObj = comphelper::getUnoTunnelImplementation<ScModelObj>(xDocSrc);
3772  ScDocShell* pDocShellSrc = static_cast<ScDocShell*>(pObj->GetEmbeddedObject());
3773 
3774  // SourceSheet Position and does srcName exists ?
3775  SCTAB nIndexSrc;
3776  if ( !pDocShellSrc->GetDocument().GetTable( srcName, nIndexSrc ) )
3777  throw lang::IllegalArgumentException();
3778 
3779  // Check the validity of destination index.
3780  SCTAB nCount = rDocDest.GetTableCount();
3781  SCTAB nIndexDest = static_cast<SCTAB>(nDestPosition);
3782  if (nIndexDest > nCount || nIndexDest < 0)
3783  throw lang::IndexOutOfBoundsException();
3784 
3785  // Transfer Tab
3787  *pDocShellSrc, nIndexSrc, nIndexDest, true/*bInsertNew*/, true/*bNotifyAndPaint*/ );
3788 
3789  return nIndexDest;
3790 }
3791 
3792 // XCellRangesAccess
3793 
3794 uno::Reference< table::XCell > SAL_CALL ScTableSheetsObj::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow, sal_Int32 nSheet )
3795 {
3796  SolarMutexGuard aGuard;
3797  uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl(static_cast<sal_uInt16>(nSheet))));
3798  if (! xSheet.is())
3799  throw lang::IndexOutOfBoundsException();
3800 
3801  return xSheet->getCellByPosition(nColumn, nRow);
3802 }
3803 
3804 uno::Reference< table::XCellRange > SAL_CALL ScTableSheetsObj::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom, sal_Int32 nSheet )
3805 {
3806  SolarMutexGuard aGuard;
3807  uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl(static_cast<sal_uInt16>(nSheet))));
3808  if (! xSheet.is())
3809  throw lang::IndexOutOfBoundsException();
3810 
3811  return xSheet->getCellRangeByPosition(nLeft, nTop, nRight, nBottom);
3812 }
3813 
3814 uno::Sequence < uno::Reference< table::XCellRange > > SAL_CALL ScTableSheetsObj::getCellRangesByName( const OUString& aRange )
3815 {
3816  SolarMutexGuard aGuard;
3817  uno::Sequence < uno::Reference < table::XCellRange > > xRet;
3818 
3819  ScRangeList aRangeList;
3820  ScDocument& rDoc = pDocShell->GetDocument();
3822  throw lang::IllegalArgumentException();
3823 
3824  size_t nCount = aRangeList.size();
3825  if (!nCount)
3826  throw lang::IllegalArgumentException();
3827 
3828  xRet.realloc(nCount);
3829  for( size_t nIndex = 0; nIndex < nCount; nIndex++ )
3830  {
3831  const ScRange & rRange = aRangeList[ nIndex ];
3832  xRet[nIndex] = new ScCellRangeObj(pDocShell, rRange);
3833  }
3834 
3835  return xRet;
3836 }
3837 
3838 // XEnumerationAccess
3839 
3840 uno::Reference<container::XEnumeration> SAL_CALL ScTableSheetsObj::createEnumeration()
3841 {
3842  SolarMutexGuard aGuard;
3843  return new ScIndexEnumeration(this, "com.sun.star.sheet.SpreadsheetsEnumeration");
3844 }
3845 
3846 // XIndexAccess
3847 
3848 sal_Int32 SAL_CALL ScTableSheetsObj::getCount()
3849 {
3850  SolarMutexGuard aGuard;
3851  if (pDocShell)
3852  return pDocShell->GetDocument().GetTableCount();
3853  return 0;
3854 }
3855 
3856 uno::Any SAL_CALL ScTableSheetsObj::getByIndex( sal_Int32 nIndex )
3857 {
3858  SolarMutexGuard aGuard;
3859  uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByIndex_Impl(nIndex));
3860  if (!xSheet.is())
3861  throw lang::IndexOutOfBoundsException();
3862 
3863  return uno::makeAny(xSheet);
3864 
3865 // return uno::Any();
3866 }
3867 
3869 {
3870  SolarMutexGuard aGuard;
3872 }
3873 
3875 {
3876  SolarMutexGuard aGuard;
3877  return ( getCount() != 0 );
3878 }
3879 
3880 // XNameAccess
3881 
3882 uno::Any SAL_CALL ScTableSheetsObj::getByName( const OUString& aName )
3883 {
3884  SolarMutexGuard aGuard;
3885  uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByName_Impl(aName));
3886  if (!xSheet.is())
3887  throw container::NoSuchElementException();
3888 
3889  return uno::makeAny(xSheet);
3890 }
3891 
3892 uno::Sequence<OUString> SAL_CALL ScTableSheetsObj::getElementNames()
3893 {
3894  SolarMutexGuard aGuard;
3895  if (pDocShell)
3896  {
3897  ScDocument& rDoc = pDocShell->GetDocument();
3898  SCTAB nCount = rDoc.GetTableCount();
3899  OUString aName;
3900  uno::Sequence<OUString> aSeq(nCount);
3901  OUString* pAry = aSeq.getArray();
3902  for (SCTAB i=0; i<nCount; i++)
3903  {
3904  rDoc.GetName( i, aName );
3905  pAry[i] = aName;
3906  }
3907  return aSeq;
3908  }
3909  return uno::Sequence<OUString>();
3910 }
3911 
3912 sal_Bool SAL_CALL ScTableSheetsObj::hasByName( const OUString& aName )
3913 {
3914  SolarMutexGuard aGuard;
3915  if (pDocShell)
3916  {
3917  SCTAB nIndex;
3918  if ( pDocShell->GetDocument().GetTable( aName, nIndex ) )
3919  return true;
3920  }
3921  return false;
3922 }
3923 
3925  pDocShell( pDocSh ),
3926  nTab ( nT ),
3927  nStartCol( nSC ),
3928  nEndCol ( nEC )
3929 {
3931 }
3932 
3934 {
3935  SolarMutexGuard g;
3936 
3937  if (pDocShell)
3939 }
3940 
3942 {
3943  if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) )
3944  {
3946  }
3947  else if ( rHint.GetId() == SfxHintId::Dying )
3948  {
3949  pDocShell = nullptr; // became invalid
3950  }
3951 }
3952 
3953 // XTableColumns
3954 
3956 {
3957  SCCOL nCol = static_cast<SCCOL>(nIndex) + nStartCol;
3958  if ( pDocShell && nCol <= nEndCol )
3959  return new ScTableColumnObj( pDocShell, nCol, nTab );
3960 
3961  return nullptr; // wrong index
3962 }
3963 
3965 {
3966  SCCOL nCol = 0;
3967  if ( ::AlphaToCol( pDocShell->GetDocument(), nCol, aName) )
3968  if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
3969  return new ScTableColumnObj( pDocShell, nCol, nTab );
3970 
3971  return nullptr;
3972 }
3973 
3974 void SAL_CALL ScTableColumnsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
3975 {
3976  SolarMutexGuard aGuard;
3977  bool bDone = false;
3978  if ( pDocShell )
3979  {
3980  const ScDocument& rDoc = pDocShell->GetDocument();
3981  if ( nCount > 0 && nPosition >= 0 && nStartCol+nPosition <= nEndCol &&
3982  nStartCol+nPosition+nCount-1 <= rDoc.MaxCol() )
3983  {
3984  ScRange aRange( static_cast<SCCOL>(nStartCol+nPosition), 0, nTab,
3985  static_cast<SCCOL>(nStartCol+nPosition+nCount-1), rDoc.MaxRow(), nTab );
3986  bDone = pDocShell->GetDocFunc().InsertCells( aRange, nullptr, INS_INSCOLS_BEFORE, true, true );
3987  }
3988  }
3989  if (!bDone)
3990  throw uno::RuntimeException(); // no other exceptions specified
3991 }
3992 
3993 void SAL_CALL ScTableColumnsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
3994 {
3995  SolarMutexGuard aGuard;
3996  bool bDone = false;
3997  // the range to be deleted has to lie within the object
3998  if ( pDocShell )
3999  {
4000  const ScDocument& rDoc = pDocShell->GetDocument();
4001  if ( nCount > 0 && nIndex >= 0 && nStartCol+nIndex+nCount-1 <= nEndCol )
4002  {
4003  ScRange aRange( static_cast<SCCOL>(nStartCol+nIndex), 0, nTab,
4004  static_cast<SCCOL>(nStartCol+nIndex+nCount-1), rDoc.MaxRow(), nTab );
4005  bDone = pDocShell->GetDocFunc().DeleteCells( aRange, nullptr, DelCellCmd::Cols, true );
4006  }
4007  }
4008  if (!bDone)
4009  throw uno::RuntimeException(); // no other exceptions specified
4010 }
4011 
4012 // XEnumerationAccess
4013 
4014 uno::Reference<container::XEnumeration> SAL_CALL ScTableColumnsObj::createEnumeration()
4015 {
4016  SolarMutexGuard aGuard;
4017  return new ScIndexEnumeration(this, "com.sun.star.table.TableColumnsEnumeration");
4018 }
4019 
4020 // XIndexAccess
4021 
4022 sal_Int32 SAL_CALL ScTableColumnsObj::getCount()
4023 {
4024  SolarMutexGuard aGuard;
4025  return nEndCol - nStartCol + 1;
4026 }
4027 
4028 uno::Any SAL_CALL ScTableColumnsObj::getByIndex( sal_Int32 nIndex )
4029 {
4030  SolarMutexGuard aGuard;
4031  uno::Reference<table::XCellRange> xColumn(GetObjectByIndex_Impl(nIndex));
4032  if (!xColumn.is())
4033  throw lang::IndexOutOfBoundsException();
4034 
4035  return uno::makeAny(xColumn);
4036 
4037 }
4038 
4040 {
4041  SolarMutexGuard aGuard;
4043 }
4044 
4046 {
4047  SolarMutexGuard aGuard;
4048  return ( getCount() != 0 );
4049 }
4050 
4051 uno::Any SAL_CALL ScTableColumnsObj::getByName( const OUString& aName )
4052 {
4053  SolarMutexGuard aGuard;
4054  uno::Reference<table::XCellRange> xColumn(GetObjectByName_Impl(aName));
4055  if (!xColumn.is())
4056  throw container::NoSuchElementException();
4057 
4058  return uno::makeAny(xColumn);
4059 }
4060 
4061 uno::Sequence<OUString> SAL_CALL ScTableColumnsObj::getElementNames()
4062 {
4063  SolarMutexGuard aGuard;
4064  SCCOL nCount = nEndCol - nStartCol + 1;
4065  uno::Sequence<OUString> aSeq(nCount);
4066  OUString* pAry = aSeq.getArray();
4067  for (SCCOL i=0; i<nCount; i++)
4068  pAry[i] = ::ScColToAlpha( nStartCol + i );
4069 
4070  return aSeq;
4071 }
4072 
4073 sal_Bool SAL_CALL ScTableColumnsObj::hasByName( const OUString& aName )
4074 {
4075  SolarMutexGuard aGuard;
4076  SCCOL nCol = 0;
4077  if ( ::AlphaToCol( pDocShell->GetDocument(), nCol, aName) )
4078  if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
4079  return true;
4080 
4081  return false; // not found
4082 }
4083 
4084 // XPropertySet
4085 
4086 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableColumnsObj::getPropertySetInfo()
4087 {
4088  SolarMutexGuard aGuard;
4089  static uno::Reference<beans::XPropertySetInfo> aRef(
4091  return aRef;
4092 }
4093 
4095  const OUString& aPropertyName, const uno::Any& aValue )
4096 {
4097  SolarMutexGuard aGuard;
4098  if (!pDocShell)
4099  throw uno::RuntimeException();
4100 
4101  std::vector<sc::ColRowSpan> aColArr(1, sc::ColRowSpan(nStartCol,nEndCol));
4102  ScDocFunc& rFunc = pDocShell->GetDocFunc();
4103 
4104  if ( aPropertyName == SC_UNONAME_CELLWID )
4105  {
4106  sal_Int32 nNewWidth = 0;
4107  if ( aValue >>= nNewWidth )
4108  rFunc.SetWidthOrHeight(
4109  true, aColArr, nTab, SC_SIZE_ORIGINAL, static_cast<sal_uInt16>(HMMToTwips(nNewWidth)), true, true);
4110  }
4111  else if ( aPropertyName == SC_UNONAME_CELLVIS )
4112  {
4113  bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
4115  rFunc.SetWidthOrHeight(true, aColArr, nTab, eMode, 0, true, true);
4116  // SC_SIZE_DIRECT with size 0: hide
4117  }
4118  else if ( aPropertyName == SC_UNONAME_OWIDTH )
4119  {
4120  bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
4121  if (bOpt)
4122  rFunc.SetWidthOrHeight(
4123  true, aColArr, nTab, SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, true, true);
4124  // sal_False for columns currently has no effect
4125  }
4126  else if ( aPropertyName == SC_UNONAME_NEWPAGE || aPropertyName == SC_UNONAME_MANPAGE )
4127  {
4129  bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
4130  for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
4131  if (bSet)
4132  rFunc.InsertPageBreak( true, ScAddress(nCol,0,nTab), true, true );
4133  else
4134  rFunc.RemovePageBreak( true, ScAddress(nCol,0,nTab), true, true );
4135  }
4136 }
4137 
4138 uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const OUString& aPropertyName )
4139 {
4140  SolarMutexGuard aGuard;
4141  if (!pDocShell)
4142  throw uno::RuntimeException();
4143 
4144  ScDocument& rDoc = pDocShell->GetDocument();
4145  uno::Any aAny;
4146 
4148 
4149  if ( aPropertyName == SC_UNONAME_CELLWID )
4150  {
4151  // for hidden column, return original height
4152  sal_uInt16 nWidth = rDoc.GetOriginalWidth( nStartCol, nTab );
4153  aAny <<= static_cast<sal_Int32>(TwipsToHMM(nWidth));
4154  }
4155  else if ( aPropertyName == SC_UNONAME_CELLVIS )
4156  {
4157  bool bVis = !rDoc.ColHidden(nStartCol, nTab);
4158  aAny <<= bVis;
4159  }
4160  else if ( aPropertyName == SC_UNONAME_OWIDTH )
4161  {
4162  bool bOpt = !(rDoc.GetColFlags( nStartCol, nTab ) & CRFlags::ManualSize);
4163  aAny <<= bOpt;
4164  }
4165  else if ( aPropertyName == SC_UNONAME_NEWPAGE )
4166  {
4167  ScBreakType nBreak = rDoc.HasColBreak(nStartCol, nTab);
4168  aAny <<= (nBreak != ScBreakType::NONE);
4169  }
4170  else if ( aPropertyName == SC_UNONAME_MANPAGE )
4171  {
4172  ScBreakType nBreak = rDoc.HasColBreak(nStartCol, nTab);
4173  aAny <<= bool(nBreak & ScBreakType::Manual);
4174  }
4175 
4176  return aAny;
4177 }
4178 
4180 
4182  pDocShell( pDocSh ),
4183  nTab ( nT ),
4184  nStartRow( nSR ),
4185  nEndRow ( nER )
4186 {
4187  pDocShell->GetDocument().AddUnoObject(*this);
4188 }
4189 
4191 {
4192  SolarMutexGuard g;
4193 
4194  if (pDocShell)
4196 }
4197 
4199 {
4200  if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) )
4201  {
4203  }
4204  else if ( rHint.GetId() == SfxHintId::Dying )
4205  {
4206  pDocShell = nullptr; // became invalid
4207  }
4208 }
4209 
4210 // XTableRows
4211 
4213 {
4214  SCROW nRow = static_cast<SCROW>(nIndex) + nStartRow;
4215  if ( pDocShell && nRow <= nEndRow )
4216  return new ScTableRowObj( pDocShell, nRow, nTab );
4217 
4218  return nullptr; // wrong index
4219 }
4220 
4221 void SAL_CALL ScTableRowsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
4222 {
4223  SolarMutexGuard aGuard;
4224  bool bDone = false;
4225  if ( pDocShell )
4226  {
4227  const ScDocument& rDoc = pDocShell->GetDocument();
4228  if ( nCount > 0 && nPosition >= 0 && nStartRow+nPosition <= nEndRow &&
4229  nStartRow+nPosition+nCount-1 <= rDoc.MaxRow() )
4230  {
4231  ScRange aRange( 0, static_cast<SCROW>(nStartRow+nPosition), nTab,
4232  rDoc.MaxCol(), static_cast<SCROW>(nStartRow+nPosition+nCount-1), nTab );
4233  bDone = pDocShell->GetDocFunc().InsertCells( aRange, nullptr, INS_INSROWS_BEFORE, true, true );
4234  }
4235  }
4236  if (!bDone)
4237  throw uno::RuntimeException(); // no other exceptions specified
4238 }
4239 
4240 void SAL_CALL ScTableRowsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
4241 {
4242  SolarMutexGuard aGuard;
4243  bool bDone = false;
4244  // the range to be deleted has to lie within the object
4245  if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartRow+nIndex+nCount-1 <= nEndRow )
4246  {
4247  const ScDocument& rDoc = pDocShell->GetDocument();
4248  ScRange aRange( 0, static_cast<SCROW>(nStartRow+nIndex), nTab,
4249  rDoc.MaxCol(), static_cast<SCROW>(nStartRow+nIndex+nCount-1), nTab );
4250  bDone = pDocShell->GetDocFunc().DeleteCells( aRange, nullptr, DelCellCmd::Rows, true );
4251  }
4252  if (!bDone)
4253  throw uno::RuntimeException(); // no other exceptions specified
4254 }
4255 
4256 // XEnumerationAccess
4257 
4258 uno::Reference<container::XEnumeration> SAL_CALL ScTableRowsObj::createEnumeration()
4259 {
4260  SolarMutexGuard aGuard;
4261  return new ScIndexEnumeration(this, "com.sun.star.table.TableRowsEnumeration");
4262 }
4263 
4264 // XIndexAccess
4265 
4266 sal_Int32 SAL_CALL ScTableRowsObj::getCount()
4267 {
4268  SolarMutexGuard aGuard;
4269  return nEndRow - nStartRow + 1;
4270 }
4271 
4272 uno::Any SAL_CALL ScTableRowsObj::getByIndex( sal_Int32 nIndex )
4273 {
4274  SolarMutexGuard aGuard;
4275  uno::Reference<table::XCellRange> xRow(GetObjectByIndex_Impl(nIndex));
4276  if (!xRow.is())
4277  throw lang::IndexOutOfBoundsException();
4278 
4279  return uno::makeAny(xRow);
4280 }
4281 
4283 {
4284  SolarMutexGuard aGuard;
4286 }
4287 
4289 {
4290  SolarMutexGuard aGuard;
4291  return ( getCount() != 0 );
4292 }
4293 
4294 // XPropertySet
4295 
4296 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableRowsObj::getPropertySetInfo()
4297 {
4298  SolarMutexGuard aGuard;
4299  static uno::Reference<beans::XPropertySetInfo> aRef(
4301  return aRef;
4302 }
4303 
4305  const OUString& aPropertyName, const uno::Any& aValue )
4306 {
4307  SolarMutexGuard aGuard;
4308  if (!pDocShell)
4309  throw uno::RuntimeException();
4310 
4311  ScDocFunc& rFunc = pDocShell->GetDocFunc();
4312  ScDocument& rDoc = pDocShell->GetDocument();
4313  std::vector<sc::ColRowSpan> aRowArr(1, sc::ColRowSpan(nStartRow,nEndRow));
4314 
4315  if ( aPropertyName == SC_UNONAME_OHEIGHT )
4316  {
4317  sal_Int32 nNewHeight = 0;
4318  if ( rDoc.IsImportingXML() && ( aValue >>= nNewHeight ) )
4319  {
4320  // used to set the stored row height for rows with optimal height when loading.
4321 
4322  // TODO: It's probably cleaner to use a different property name
4323  // for this.
4324  rDoc.SetRowHeightOnly( nStartRow, nEndRow, nTab, static_cast<sal_uInt16>(HMMToTwips(nNewHeight)) );
4325  }
4326  else
4327  {
4328  bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
4329  if (bOpt)
4330  rFunc.SetWidthOrHeight(false, aRowArr, nTab, SC_SIZE_OPTIMAL, 0, true, true);
4331  else
4332  {
4334  }
4335  }
4336  }
4337  else if ( aPropertyName == SC_UNONAME_CELLHGT )
4338  {
4339  sal_Int32 nNewHeight = 0;
4340  if ( aValue >>= nNewHeight )
4341  {
4342  if (rDoc.IsImportingXML())
4343  {
4344  // TODO: This is a band-aid fix. Eventually we need to
4345  // re-work ods' style import to get it to set styles to
4346  // ScDocument directly.
4347  rDoc.SetRowHeightOnly( nStartRow, nEndRow, nTab, static_cast<sal_uInt16>(HMMToTwips(nNewHeight)) );
4348  rDoc.SetManualHeight( nStartRow, nEndRow, nTab, true );
4349  }
4350  else
4351  rFunc.SetWidthOrHeight(
4352  false, aRowArr, nTab, SC_SIZE_ORIGINAL, static_cast<sal_uInt16>(HMMToTwips(nNewHeight)), true, true);
4353  }
4354  }
4355  else if ( aPropertyName == SC_UNONAME_CELLVIS )
4356  {
4357  bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
4359  rFunc.SetWidthOrHeight(false, aRowArr, nTab, eMode, 0, true, true);
4360  // SC_SIZE_DIRECT with size 0: hide
4361  }
4362  else if ( aPropertyName == SC_UNONAME_VISFLAG )
4363  {
4364  // #i116460# Shortcut to only set the flag, without drawing layer update etc.
4365  // Should only be used from import filters.
4367  }
4368  else if ( aPropertyName == SC_UNONAME_CELLFILT )
4369  {
4371  if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
4372  rDoc.SetRowFiltered(nStartRow, nEndRow, nTab, true);
4373  else
4374  rDoc.SetRowFiltered(nStartRow, nEndRow, nTab, false);
4375  }
4376  else if ( aPropertyName == SC_UNONAME_NEWPAGE || aPropertyName == SC_UNONAME_MANPAGE )
4377  {
4379  bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
4380  for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
4381  if (bSet)
4382  rFunc.InsertPageBreak( false, ScAddress(0,nRow,nTab), true, true );
4383  else
4384  rFunc.RemovePageBreak( false, ScAddress(0,nRow,nTab), true, true );
4385  }
4386  else if ( aPropertyName == SC_UNONAME_CELLBACK || aPropertyName == SC_UNONAME_CELLTRAN )
4387  {
4388  // #i57867# Background color is specified for row styles in the file format,
4389  // so it has to be supported along with the row properties (import only).
4390 
4391  // Use ScCellRangeObj to set the property for all cells in the rows
4392  // (this means, the "row attribute" must be set before individual cell attributes).
4393 
4394  ScRange aRange( 0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab );
4395  uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
4396  xRangeObj->setPropertyValue( aPropertyName, aValue );
4397  }
4398 }
4399 
4400 uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const OUString& aPropertyName )
4401 {
4402  SolarMutexGuard aGuard;
4403  if (!pDocShell)
4404  throw uno::RuntimeException();
4405 
4406  ScDocument& rDoc = pDocShell->GetDocument();
4407  uno::Any aAny;
4408 
4410 
4411  if ( aPropertyName == SC_UNONAME_CELLHGT )
4412  {
4413  // for hidden row, return original height
4414  sal_uInt16 nHeight = rDoc.GetOriginalHeight( nStartRow, nTab );
4415  aAny <<= static_cast<sal_Int32>(TwipsToHMM(nHeight));
4416  }
4417  else if ( aPropertyName == SC_UNONAME_CELLVIS )
4418  {
4419  SCROW nLastRow;
4420  bool bVis = !rDoc.RowHidden(nStartRow, nTab, nullptr, &nLastRow);
4421  aAny <<= bVis;
4422  }
4423  else if ( aPropertyName == SC_UNONAME_CELLFILT )
4424  {
4425  bool bVis = rDoc.RowFiltered(nStartRow, nTab);
4426  aAny <<= bVis;
4427  }
4428  else if ( aPropertyName == SC_UNONAME_OHEIGHT )
4429  {
4430  bool bOpt = !(rDoc.GetRowFlags( nStartRow, nTab ) & CRFlags::ManualSize);
4431  aAny <<= bOpt;
4432  }
4433  else if ( aPropertyName == SC_UNONAME_NEWPAGE )
4434  {
4435  ScBreakType nBreak = rDoc.HasRowBreak(nStartRow, nTab);
4436  aAny <<= (nBreak != ScBreakType::NONE);
4437  }
4438  else if ( aPropertyName == SC_UNONAME_MANPAGE )
4439  {
4440  ScBreakType nBreak = rDoc.HasRowBreak(nStartRow, nTab);
4441  aAny <<= bool(nBreak & ScBreakType::Manual);
4442  }
4443  else if ( aPropertyName == SC_UNONAME_CELLBACK || aPropertyName == SC_UNONAME_CELLTRAN )
4444  {
4445  // Use ScCellRangeObj to get the property from the cell range
4446  // (for completeness only, this is not used by the XML filter).
4447 
4448  ScRange aRange( 0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab );
4449  uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
4450  aAny = xRangeObj->getPropertyValue( aPropertyName );
4451  }
4452 
4453  return aAny;
4454 }
4455 
4457 
4459 {
4460 }
4461 
4462 // XPropertySet
4463 
4464 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSpreadsheetSettingsObj::getPropertySetInfo()
4465 {
4466  return nullptr;
4467 }
4468 
4470  const OUString& /* aPropertyName */, const uno::Any& /* aValue */ )
4471 {
4472 }
4473 
4474 uno::Any SAL_CALL ScSpreadsheetSettingsObj::getPropertyValue( const OUString& /* aPropertyName */ )
4475 {
4476  return uno::Any();
4477 }
4478 
4480 
4482  pDocShell( pDocSh ),
4483  nTab( nT )
4484 {
4485  pDocShell->GetDocument().AddUnoObject(*this);
4486 }
4487 
4489 {
4490  SolarMutexGuard g;
4491 
4492  if (pDocShell)
4494 }
4495 
4497 {
4499 
4500  if ( rHint.GetId() == SfxHintId::Dying )
4501  {
4502  pDocShell = nullptr; // became invalid
4503  }
4504 }
4505 
4506 bool ScAnnotationsObj::GetAddressByIndex_Impl( sal_Int32 nIndex, ScAddress& rPos ) const
4507 {
4508  if (!pDocShell)
4509  return false;
4510 
4511  ScDocument& rDoc = pDocShell->GetDocument();
4512  rPos = rDoc.GetNotePosition(nIndex, nTab);
4513  return rPos.IsValid();
4514 }
4515 
4517 {
4518  if (pDocShell)
4519  {
4520  ScAddress aPos;
4521  if ( GetAddressByIndex_Impl( nIndex, aPos ) )
4522  return new ScAnnotationObj( pDocShell, aPos );
4523  }
4524  return nullptr;
4525 }
4526 
4527 // XSheetAnnotations
4528 
4530  const table::CellAddress& aPosition, const OUString& rText )
4531 {
4532  SolarMutexGuard aGuard;
4533  if (pDocShell)
4534  {
4535  OSL_ENSURE( aPosition.Sheet == nTab, "addAnnotation with a wrong Sheet" );
4536  ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab );
4537  pDocShell->GetDocFunc().ReplaceNote( aPos, rText, nullptr, nullptr, true );
4538  }
4539 }
4540 
4541 void SAL_CALL ScAnnotationsObj::removeByIndex( sal_Int32 nIndex )
4542 {
4543  SolarMutexGuard aGuard;
4544  if (pDocShell)
4545  {
4546  ScAddress aPos;
4547  if ( GetAddressByIndex_Impl( nIndex, aPos ) )
4548  {
4550  aMarkData.SelectTable( aPos.Tab(), true );
4551  aMarkData.SetMultiMarkArea( ScRange(aPos) );
4552 
4553  pDocShell->GetDocFunc().DeleteContents( aMarkData, InsertDeleteFlags::NOTE, true, true );
4554  }
4555  }
4556 }
4557 
4558 // XEnumerationAccess
4559 
4560 uno::Reference<container::XEnumeration> SAL_CALL ScAnnotationsObj::createEnumeration()
4561 {
4563 
4564  SolarMutexGuard aGuard;
4565  return new ScIndexEnumeration(this, "com.sun.star.sheet.CellAnnotationsEnumeration");
4566 }
4567 
4568 // XIndexAccess
4569 
4570 sal_Int32 SAL_CALL ScAnnotationsObj::getCount()
4571 {
4572  SolarMutexGuard aGuard;
4573  sal_Int32 nCount = 0;
4574  if (pDocShell)
4575  {
4576  const ScDocument& rDoc = pDocShell->GetDocument();
4577  for (SCCOL nCol : rDoc.GetColumnsRange(nTab, 0, rDoc.MaxCol()))
4578  nCount += rDoc.GetNoteCount(nTab, nCol);
4579  }
4580  return nCount;
4581 }
4582 
4583 uno::Any SAL_CALL ScAnnotationsObj::getByIndex( sal_Int32 nIndex )
4584 {
4585  SolarMutexGuard aGuard;
4586  uno::Reference<sheet::XSheetAnnotation> xAnnotation(GetObjectByIndex_Impl(nIndex));
4587  if (!xAnnotation.is())
4588  throw lang::IndexOutOfBoundsException();
4589 
4590  return uno::makeAny(xAnnotation);
4591 }
4592 
4594 {
4595  SolarMutexGuard aGuard;
4597 }
4598 
4600 {
4601  SolarMutexGuard aGuard;
4602  return ( getCount() != 0 );
4603 }
4604 
4606  pDocShell( pDocSh ),
4607  nTab ( nT )
4608 {
4610 }
4611 
4613 {
4614  SolarMutexGuard g;
4615 
4616  if (pDocShell)
4618 }
4619 
4621 {
4622  if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) )
4623  {
4625  }
4626  else if ( rHint.GetId() == SfxHintId::Dying )
4627  {
4628  pDocShell = nullptr; // became invalid
4629  }
4630 }
4631 
4632 // XScenarios
4633 
4634 bool ScScenariosObj::GetScenarioIndex_Impl( const OUString& rName, SCTAB& rIndex )
4635 {
4637 
4638  if ( pDocShell )
4639  {
4640  OUString aTabName;
4641  ScDocument& rDoc = pDocShell->GetDocument();
4642  SCTAB nCount = static_cast<SCTAB>(getCount());
4643  for (SCTAB i=0; i<nCount; i++)
4644  if (rDoc.GetName( nTab+i+1, aTabName ))
4645  if (aTabName == rName)
4646  {
4647  rIndex = i;
4648  return true;
4649  }
4650  }
4651 
4652  return false;
4653 }
4654 
4656 {
4657  sal_uInt16 nCount = static_cast<sal_uInt16>(getCount());
4658  if ( pDocShell && nIndex >= 0 && nIndex < nCount )
4659  return new ScTableSheetObj( pDocShell, nTab+static_cast<SCTAB>(nIndex)+1 );
4660 
4661  return nullptr; // no document or wrong index
4662 }
4663 
4665 {
4666  SCTAB nIndex;
4667  if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
4668  return new ScTableSheetObj( pDocShell, nTab+nIndex+1 );
4669 
4670  return nullptr; // not found
4671 }
4672 
4673 void SAL_CALL ScScenariosObj::addNewByName( const OUString& aName,
4674  const uno::Sequence<table::CellRangeAddress>& aRanges,
4675  const OUString& aComment )
4676 {
4677  SolarMutexGuard aGuard;
4678  if ( pDocShell )
4679  {
4681  aMarkData.SelectTable( nTab, true );
4682 
4683  for (const table::CellRangeAddress& rRange : aRanges)
4684  {
4685  OSL_ENSURE( rRange.Sheet == nTab, "addScenario with a wrong Tab" );
4686  ScRange aRange( static_cast<SCCOL>(rRange.StartColumn), static_cast<SCROW>(rRange.StartRow), nTab,
4687  static_cast<SCCOL>(rRange.EndColumn), static_cast<SCROW>(rRange.EndRow), nTab );
4688 
4689  aMarkData.SetMultiMarkArea( aRange );
4690  }
4691 
4694 
4695  pDocShell->MakeScenario( nTab, aName, aComment, COL_LIGHTGRAY, nFlags, aMarkData );
4696  }
4697 }
4698 
4699 void SAL_CALL ScScenariosObj::removeByName( const OUString& aName )
4700 {
4701  SolarMutexGuard aGuard;
4702  SCTAB nIndex;
4703  if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
4704  pDocShell->GetDocFunc().DeleteTable( nTab+nIndex+1, true );
4705 }
4706 
4707 // XEnumerationAccess
4708 
4709 uno::Reference<container::XEnumeration> SAL_CALL ScScenariosObj::createEnumeration()
4710 {
4711  SolarMutexGuard aGuard;
4712  return new ScIndexEnumeration(this, "com.sun.star.sheet.ScenariosEnumeration");
4713 }
4714 
4715 // XIndexAccess
4716 
4717 sal_Int32 SAL_CALL ScScenariosObj::getCount()
4718 {
4719  SolarMutexGuard aGuard;
4720  SCTAB nCount = 0;
4721  if ( pDocShell )
4722  {
4723  ScDocument& rDoc = pDocShell->GetDocument();
4724  if (!rDoc.IsScenario(nTab))
4725  {
4726  SCTAB nTabCount = rDoc.GetTableCount();
4727  SCTAB nNext = nTab + 1;
4728  while (nNext < nTabCount && rDoc.IsScenario(nNext))
4729  {
4730  ++nCount;
4731  ++nNext;
4732  }
4733  }
4734  }
4735  return nCount;
4736 }
4737 
4738 uno::Any SAL_CALL ScScenariosObj::getByIndex( sal_Int32 nIndex )
4739 {
4740  SolarMutexGuard aGuard;
4741  uno::Reference<sheet::XScenario> xScen(GetObjectByIndex_Impl(nIndex));
4742  if (!xScen.is())
4743  throw lang::IndexOutOfBoundsException();
4744 
4745  return uno::makeAny(xScen);
4746 }
4747 
4749 {
4750  SolarMutexGuard aGuard;
4752 }
4753 
4755 {
4756  SolarMutexGuard aGuard;
4757  return ( getCount() != 0 );
4758 }
4759 
4760 uno::Any SAL_CALL ScScenariosObj::getByName( const OUString& aName )
4761 {
4762  SolarMutexGuard aGuard;
4763  uno::Reference<sheet::XScenario> xScen(GetObjectByName_Impl(aName));
4764  if (!xScen.is())
4765  throw container::NoSuchElementException();
4766 
4767  return uno::makeAny(xScen);
4768 }
4769 
4770 uno::Sequence<OUString> SAL_CALL ScScenariosObj::getElementNames()
4771 {
4772  SolarMutexGuard aGuard;
4773  SCTAB nCount = static_cast<SCTAB>(getCount());
4774  uno::Sequence<OUString> aSeq(nCount);
4775 
4776  if ( pDocShell ) // otherwise Count = 0
4777  {
4778  OUString aTabName;
4779  ScDocument& rDoc = pDocShell->GetDocument();
4780  OUString* pAry = aSeq.getArray();
4781  for (SCTAB i=0; i<nCount; i++)
4782  if (rDoc.GetName( nTab+i+1, aTabName ))
4783  pAry[i] = aTabName;
4784  }
4785 
4786  return aSeq;
4787 }
4788 
4789 sal_Bool SAL_CALL ScScenariosObj::hasByName( const OUString& aName )
4790 {
4791  SolarMutexGuard aGuard;
4792  SCTAB nIndex;
4793  return GetScenarioIndex_Impl( aName, nIndex );
4794 }
4795 
4796 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual css::sheet::GoalResult SAL_CALL seekGoal(const css::table::CellAddress &aFormulaPosition, const css::table::CellAddress &aVariablePosition, const OUString &aGoalValue) override
XGoalSeek.
Definition: docuno.cxx:2474
SC_DLLPUBLIC bool IsDocProtected() const
Definition: documen3.cxx:1860
Stores the selection in the ScPrintFuncCache so it is only used for the same selection again...
Definition: pfuncache.hxx:46
virtual void SAL_CALL lockControllers() override
Definition: docuno.cxx:2349
ScPrintSelectionMode GetMode() const
Definition: pfuncache.hxx:62
static Type GetProviderType(const OUString &rServiceName)
Definition: servuno.cxx:371
SC_DLLPUBLIC bool GetPrintArea(SCTAB nTab, SCCOL &rEndCol, SCROW &rEndRow, bool bNotes=true) const
Definition: documen2.cxx:573
#define SC_UNO_IGNORECASE
Definition: unonames.hxx:502
SCTAB nTab
Collection belongs to the sheet.
Definition: docuno.hxx:671
virtual void SAL_CALL acquire() override
SfxViewFrame * GetViewFrame() const
ScDBFunc * GetView() const
Definition: viewdata.hxx:356
virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
Definition: docuno.cxx:4028
OUString const & getRuntimeUID() const
long Width() const
virtual sal_Int32 SAL_CALL getFormulaCellNumberLimit() override
Definition: docuno.cxx:3440
#define SCMODELOBJ_SERVICE
Definition: docuno.cxx:230
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
XPropertySet.
Definition: docuno.cxx:4296
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
XEnumerationAccess.
Definition: docuno.cxx:4258
bool setGraphicSelection(int nType, int nX, int nY, double fScaleX=1.0, double fScaleY=1.0)
virtual void SAL_CALL disableOpcodeSubsetTest() override
Definition: docuno.cxx:3423
void SetAutoComplete(bool bNew)
Definition: appoptio.hxx:54
#define SC_POSITIONLEFT
#define SC_UNO_ISADJUSTHEIGHTENABLED
Definition: unonames.hxx:519
virtual css::uno::Type SAL_CALL getElementType() override
XElementAccess.
Definition: docuno.cxx:4282
void SetDigitLanguage(LanguageType)
void setGrabBagItem(const css::uno::Any &rVal)
#define SC_UNO_SPELLONLINE
Definition: unonames.hxx:509
css::uno::Reference< css::uno::XInterface > create(OUString const &aServiceSpecifier, css::uno::Sequence< css::uno::Any > const *arguments)
Definition: docuno.cxx:2925
long GetWidth() const
void UnlockPaint()
Definition: docsh3.cxx:320
virtual void SAL_CALL enableAutomaticDeviceSelection(sal_Bool bForce) override
Definition: docuno.cxx:3308
SfxHintId
bool hasValidSignatures() const
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
XNameAccess.
Definition: docuno.cxx:4760
void setOpenCLConfigToDefault()
Definition: calcconfig.cxx:107
void MarkToSimple()
Definition: markdata.cxx:237
virtual void SAL_CALL addChangesListener(const css::uno::Reference< css::util::XChangesListener > &aListener) override
XChangesNotifier.
Definition: docuno.cxx:3112
bool hasValue()
sal_Int32 nIndex
virtual void getCellCursor(tools::JsonWriter &rJsonWriter) override
Definition: docuno.cxx:1000
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: gridwin.cxx:1407
#define PROP_UNO_CALCASSHOWN
Definition: optuno.hxx:26
ScAddress aStart
Definition: address.hxx:500
virtual void SAL_CALL lockControllers() override
SC_DLLPUBLIC bool GetDataStart(SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow) const
Definition: documen2.cxx:641
virtual void SAL_CALL unprotect(const OUString &aPassword) override
Definition: docuno.cxx:2439
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(const OUString &aServiceSpecifier) override
XMultiServiceFactory.
Definition: docuno.cxx:3009
long GetHeight() const
void SetConsolidateDlgData(std::unique_ptr< ScConsolidateParam > pData)
Definition: documen2.cxx:1104
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
Definition: docuno.cxx:3530
static bool HasValidData(const css::uno::Reference< css::datatransfer::XTransferable > &rTransferable)
virtual const tools::Rectangle & GetCurrentBoundRect() const
SfxPrinter * GetPrinter(bool bCreateIfNotExist=true)
Definition: docsh3.cxx:450
virtual css::uno::Reference< css::sheet::XSpreadsheets > SAL_CALL getSheets() override
XSpreadsheetDocument.
Definition: docuno.cxx:1334
virtual void SAL_CALL enableOpenCL(sal_Bool bEnable) override
Definition: docuno.cxx:3283
bool Unprotect(SCTAB nTab, const OUString &rPassword, bool bApi)
Definition: docfunc.cxx:4004
#define SC_UNONAME_VISFLAG
Definition: unonames.hxx:186
static bool HitAny(const Point &aPos)
virtual void SAL_CALL removeByIndex(sal_Int32 nIndex, sal_Int32 nCount) override
Definition: docuno.cxx:3993
virtual void completeFunction(const OUString &rFunctionName) override
Definition: docuno.cxx:1156
SC_DLLPUBLIC CRFlags GetColFlags(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:4331
virtual void SAL_CALL release() override
Definition: docuno.cxx:1231
void SetAutoControlFocus(bool _bAutoControlFocus)
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: docuno.cxx:4061
virtual css::uno::Reference< css::container::XNameAccess > SAL_CALL getLinks() override
XLinkTargetSupplier.
Definition: docuno.cxx:2297
SC_DLLPUBLIC bool DeleteContents(const ScMarkData &rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi)
Definition: docfunc.cxx:566
virtual sal_Int32 SAL_CALL getCount() override
XIndexAccess.
Definition: docuno.cxx:3522
virtual void SAL_CALL unlockControllers() override
Definition: docuno.cxx:2357
osl::Mutex m_aMutex
ScTableRowObj * GetObjectByIndex_Impl(sal_Int32 nIndex) const
Definition: docuno.cxx:4212
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: docuno.cxx:3912
SCROW Row() const
Definition: address.hxx:262
ScDocShell * GetDocShell() const
Definition: cellsuno.hxx:242
ScInterpreterContext & GetThreadedContext() const
Definition: document.hxx:618
#define SC_UNO_ITERENABLED
Definition: unonames.hxx:504
static bool lcl_ParseTarget(const OUString &rTarget, ScRange &rTargetRange, tools::Rectangle &rTargetRect, bool &rIsSheet, ScDocument *pDoc, SCTAB nSourceTab)
Definition: docuno.cxx:1388
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: docuno.cxx:3566
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArguments(const OUString &ServiceSpecifier, const css::uno::Sequence< css::uno::Any > &Arguments) override
Definition: docuno.cxx:3016
ServiceType
virtual void SetChangeRecording(bool bActivate) override
Definition: docsh.cxx:3193
#define SC_ACTIVETABLE
virtual void setTextSelection(int nType, int nX, int nY) override
Definition: docuno.cxx:742
virtual css::uno::Reference< css::container::XIndexAccess > SAL_CALL getViewData() override
XViewDataSupplier.
Definition: docuno.cxx:2550
ScFormatSaveData * GetFormatSaveData()
Definition: docsh.cxx:2971
const css::uno::Reference< css::script::vba::XVBAEventProcessor > & GetVbaEventProcessor() const
Definition: document.hxx:2435
static weld::Window * GetActiveDialogParent()
Definition: docsh.cxx:2949
const Fraction & GetZoomX() const
Definition: viewdata.hxx:459
SfxBindings * GetViewBindings()
Definition: docsh4.cxx:2577
virtual void setGraphicSelection(int nType, int nX, int nY) override
Definition: docuno.cxx:853
virtual void setClientVisibleArea(const tools::Rectangle &rRectangle) override
Definition: docuno.cxx:1041
#define SC_UNONAME_OWIDTH
Definition: unonames.hxx:171
#define SC_UNO_ITERCOUNT
Definition: unonames.hxx:503
long Height() const
long TwipsToHMM(long nTwips)
Definition: global.hxx:108
virtual void postKeyEvent(int nType, int nCharCode, int nKeyCode) override
Definition: docuno.cxx:694
virtual int getPart() override
Definition: docuno.cxx:588
bool postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier, double fScaleX=1.0, double fScaleY=1.0)
ULONG m_refCount
#define SC_UNO_NAMEDRANGES
Definition: unonames.hxx:44
ScScenarioFlags
Definition: global.hxx:236
void ResetMark()
Definition: markdata.cxx:85
bool IsInputMode() const
Definition: inputhdl.hxx:185
SfxDispatcher * GetDispatcher()
virtual void SAL_CALL insertNewByName(const OUString &aName, sal_Int16 nPosition) override
XSpreadsheets.
Definition: docuno.cxx:3597
#define TWIPS_PER_PIXEL
Definition: global.hxx:88
ScDocShell * pDocShell
Definition: docuno.hxx:715
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
#define SC_UNO_APPLYFMDES
Definition: unonames.hxx:531
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: docuno.cxx:1282
int getPart() const override
See SfxViewShell::getPart().
Definition: tabvwshc.cxx:436
#define SC_UNONAME_MANPAGE
Definition: unonames.hxx:168
virtual void SAL_CALL addNewByName(const OUString &aName, const css::uno::Sequence< css::table::CellRangeAddress > &aRanges, const OUString &aComment) override
XScenarios.
Definition: docuno.cxx:4673
virtual sal_Bool SAL_CALL hasElements() override
Definition: docuno.cxx:4045
#define SC_UNO_FORBIDDEN
Definition: unonames.hxx:47
virtual css::uno::Type SAL_CALL getElementType() override
XElementAccess.
Definition: docuno.cxx:3540
static OutputDevice * lcl_GetRenderDevice(const uno::Sequence< beans::PropertyValue > &rOptions)
Definition: docuno.cxx:1364
virtual css::uno::Sequence< OUString > SAL_CALL getAvailableServiceNames() override
Definition: docuno.cxx:3037
virtual ~ScScenariosObj() override
Definition: docuno.cxx:4612
#define SC_UNO_HASVALIDSIGNATURES
Definition: unonames.hxx:516
sal_Int32 addInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
Reference< XInterface > xTarget
#define PROP_UNO_ITEREPSILON
Definition: optuno.hxx:31
ScDocShell * pDocShell
Definition: docuno.hxx:670
#define PROP_UNO_IGNORECASE
Definition: optuno.hxx:28
virtual OUString SAL_CALL getImplementationName() override
XServiceInfo.
Definition: docuno.cxx:3046
static void DrawToDev(ScDocument *pDoc, OutputDevice *pDev, double nPrintFactor, const tools::Rectangle &rBound, ScViewData *pViewData, bool bMetaFile)
Definition: printfun.cxx:443
void AfterXMLLoading()
Definition: docuno.cxx:472