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_features.h> 21 22 #include <boost/property_tree/json_parser.hpp> 23 24 #include <com/sun/star/frame/Desktop.hpp> 25 26 using namespace ::com::sun::star; 27 28 #include <scitems.hxx> 29 #include <editeng/flstitem.hxx> 30 #include <sfx2/fcontnr.hxx> 31 #include <sfx2/infobar.hxx> 32 #include <sfx2/objface.hxx> 33 #include <sfx2/docfile.hxx> 34 #include <sfx2/docfilt.hxx> 35 #include <svtools/ehdl.hxx> 36 #include <svtools/langtab.hxx> 37 #include <basic/sbxcore.hxx> 38 #include <basic/sberrors.hxx> 39 #include <svtools/sfxecode.hxx> 40 #include <svx/ofaitem.hxx> 41 #include <svl/stritem.hxx> 42 #include <svl/whiter.hxx> 43 #include <vcl/svapp.hxx> 44 #include <vcl/weld.hxx> 45 #include <svx/dataaccessdescriptor.hxx> 46 #include <svx/drawitem.hxx> 47 #include <svx/fmshell.hxx> 48 #include <sfx2/passwd.hxx> 49 #include <sfx2/filedlghelper.hxx> 50 #include <sfx2/dispatch.hxx> 51 #include <sfx2/sfxdlg.hxx> 52 #include <svl/PasswordHelper.hxx> 53 #include <svl/documentlockfile.hxx> 54 #include <svl/sharecontrolfile.hxx> 55 #include <unotools/securityoptions.hxx> 56 #include <LibreOfficeKit/LibreOfficeKitEnums.h> 57 #include <sal/log.hxx> 58 #include <unotools/charclass.hxx> 59 60 #include <comphelper/lok.hxx> 61 #include <comphelper/processfactory.hxx> 62 #include <docuno.hxx> 63 64 #include <docsh.hxx> 65 #include "docshimp.hxx" 66 #include <docfunc.hxx> 67 #include <scres.hrc> 68 #include <strings.hrc> 69 #include <stlsheet.hxx> 70 #include <stlpool.hxx> 71 #include <appoptio.hxx> 72 #include <globstr.hrc> 73 #include <global.hxx> 74 #include <dbdocfun.hxx> 75 #include <printfun.hxx> 76 #include <viewdata.hxx> 77 #include <tabvwsh.hxx> 78 #include <impex.hxx> 79 #include <undodat.hxx> 80 #include <undocell.hxx> 81 #include <inputhdl.hxx> 82 #include <dbdata.hxx> 83 #include <servobj.hxx> 84 #include <rangenam.hxx> 85 #include <scmod.hxx> 86 #include <chgviset.hxx> 87 #include <reffact.hxx> 88 #include <chartlis.hxx> 89 #include <chartpos.hxx> 90 #include <waitoff.hxx> 91 #include <tablink.hxx> 92 #include <drwlayer.hxx> 93 #include <docoptio.hxx> 94 #include <undostyl.hxx> 95 #include <rangeseq.hxx> 96 #include <chgtrack.hxx> 97 #include <com/sun/star/document/UpdateDocMode.hpp> 98 #include <scresid.hxx> 99 #include <scabstdlg.hxx> 100 #include <sharedocdlg.hxx> 101 #include <conditio.hxx> 102 #include <sheetevents.hxx> 103 #include <formulacell.hxx> 104 #include <documentlinkmgr.hxx> 105 #include <memory> 106 #include <sfx2/notebookbar/SfxNotebookBar.hxx> 107 #include <helpids.h> 108 109 #include <svx/xdef.hxx> 110 111 void ScDocShell::ReloadAllLinks() 112 { 113 m_aDocument.SetLinkFormulaNeedingCheck(false); 114 getEmbeddedObjectContainer().setUserAllowsLinkUpdate(true); 115 116 ReloadTabLinks(); 117 weld::Window *pDialogParent = GetActiveDialogParent(); 118 m_aDocument.UpdateExternalRefLinks(pDialogParent); 119 120 bool bAnyDde = m_aDocument.GetDocLinkManager().updateDdeOrOleOrWebServiceLinks(pDialogParent); 121 122 if (bAnyDde) 123 { 124 // calculate formulas and paint like in the TrackTimeHdl 125 m_aDocument.TrackFormulas(); 126 Broadcast(SfxHint(SfxHintId::ScDataChanged)); 127 128 // Should FID_DATACHANGED become asynchronous some time 129 // (e.g., with Invalidate at Window), an update needs to be forced here. 130 } 131 132 m_aDocument.UpdateAreaLinks(); 133 } 134 135 IMPL_LINK_NOARG( ScDocShell, ReloadAllLinksHdl, Button*, void ) 136 { 137 ReloadAllLinks(); 138 139 ScTabViewShell* pViewSh = GetBestViewShell(); 140 SfxViewFrame* pViewFrame = pViewSh ? pViewSh->GetFrame() : nullptr; 141 if (pViewFrame) 142 pViewFrame->RemoveInfoBar("enablecontent"); 143 SAL_WARN_IF(!pViewFrame, "sc", "expected there to be a ViewFrame"); 144 } 145 146 ScLkUpdMode ScDocShell::GetLinkUpdateModeState() const 147 { 148 const ScDocument& rDoc = GetDocument(); 149 150 ScLkUpdMode nSet = rDoc.GetLinkMode(); 151 152 if (nSet == LM_UNKNOWN) 153 { 154 ScAppOptions aAppOptions = SC_MOD()->GetAppOptions(); 155 nSet = aAppOptions.GetLinkMode(); 156 } 157 158 if (m_nCanUpdate == css::document::UpdateDocMode::NO_UPDATE) 159 nSet = LM_NEVER; 160 else if (m_nCanUpdate == css::document::UpdateDocMode::FULL_UPDATE) 161 nSet = LM_ALWAYS; 162 163 if (nSet == LM_ALWAYS 164 && !(SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks( 165 GetMedium() == nullptr ? OUString() : GetMedium()->GetName()) 166 || (IsDocShared() 167 && SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks( 168 GetSharedFileURL())))) 169 { 170 nSet = LM_ON_DEMAND; 171 } 172 if (m_nCanUpdate == css::document::UpdateDocMode::QUIET_UPDATE 173 && nSet == LM_ON_DEMAND) 174 { 175 nSet = LM_NEVER; 176 } 177 178 return nSet; 179 } 180 181 void ScDocShell::Execute( SfxRequest& rReq ) 182 { 183 const SfxItemSet* pReqArgs = rReq.GetArgs(); 184 SfxBindings* pBindings = GetViewBindings(); 185 bool bUndo (m_aDocument.IsUndoEnabled()); 186 187 sal_uInt16 nSlot = rReq.GetSlot(); 188 switch ( nSlot ) 189 { 190 case SID_SC_SETTEXT: 191 { 192 const SfxPoolItem* pColItem; 193 const SfxPoolItem* pRowItem; 194 const SfxPoolItem* pTabItem; 195 const SfxPoolItem* pTextItem; 196 if( pReqArgs && pReqArgs->HasItem( FN_PARAM_1, &pColItem ) && 197 pReqArgs->HasItem( FN_PARAM_2, &pRowItem ) && 198 pReqArgs->HasItem( FN_PARAM_3, &pTabItem ) && 199 pReqArgs->HasItem( SID_SC_SETTEXT, &pTextItem ) ) 200 { 201 // parameters are 1-based !!! 202 SCCOL nCol = static_cast<const SfxInt16Item*>(pColItem)->GetValue() - 1; 203 SCROW nRow = static_cast<const SfxInt32Item*>(pRowItem)->GetValue() - 1; 204 SCTAB nTab = static_cast<const SfxInt16Item*>(pTabItem)->GetValue() - 1; 205 206 SCTAB nTabCount = m_aDocument.GetTableCount(); 207 if ( m_aDocument.ValidCol(nCol) && m_aDocument.ValidRow(nRow) && ValidTab(nTab,nTabCount) ) 208 { 209 if ( m_aDocument.IsBlockEditable( nTab, nCol,nRow, nCol, nRow ) ) 210 { 211 OUString aVal = static_cast<const SfxStringItem*>(pTextItem)->GetValue(); 212 m_aDocument.SetString( nCol, nRow, nTab, aVal ); 213 214 PostPaintCell( nCol, nRow, nTab ); 215 SetDocumentModified(); 216 217 rReq.Done(); 218 break; 219 } 220 else // protected cell 221 { 222 #if HAVE_FEATURE_SCRIPTING 223 SbxBase::SetError( ERRCODE_BASIC_BAD_PARAMETER ); //! which error ? 224 #endif 225 break; 226 } 227 } 228 } 229 #if HAVE_FEATURE_SCRIPTING 230 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT ); 231 #endif 232 } 233 break; 234 235 case SID_SBA_IMPORT: 236 { 237 if (pReqArgs) 238 { 239 const SfxPoolItem* pItem; 240 svx::ODataAccessDescriptor aDesc; 241 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET ) 242 { 243 uno::Any aAny = static_cast<const SfxUnoAnyItem*>(pItem)->GetValue(); 244 uno::Sequence<beans::PropertyValue> aProperties; 245 if ( aAny >>= aProperties ) 246 aDesc.initializeFrom( aProperties ); 247 } 248 249 OUString sTarget; 250 if ( pReqArgs->GetItemState( FN_PARAM_1, true, &pItem ) == SfxItemState::SET ) 251 sTarget = static_cast<const SfxStringItem*>(pItem)->GetValue(); 252 253 bool bIsNewArea = true; // Default sal_True (no inquiry) 254 if ( pReqArgs->GetItemState( FN_PARAM_2, true, &pItem ) == SfxItemState::SET ) 255 bIsNewArea = static_cast<const SfxBoolItem*>(pItem)->GetValue(); 256 257 // if necessary, create new database area 258 bool bMakeArea = false; 259 if (bIsNewArea) 260 { 261 ScDBCollection* pDBColl = m_aDocument.GetDBCollection(); 262 if ( !pDBColl || !pDBColl->getNamedDBs().findByUpperName(ScGlobal::pCharClass->uppercase(sTarget)) ) 263 { 264 ScAddress aPos; 265 if ( aPos.Parse( sTarget, &m_aDocument, m_aDocument.GetAddressConvention() ) & ScRefFlags::VALID ) 266 { 267 bMakeArea = true; 268 if (bUndo) 269 { 270 OUString aStrImport = ScResId( STR_UNDO_IMPORTDATA ); 271 ViewShellId nViewShellId(-1); 272 if (ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell()) 273 nViewShellId = pViewSh->GetViewShellId(); 274 GetUndoManager()->EnterListAction( aStrImport, aStrImport, 0, nViewShellId ); 275 } 276 277 ScDBData* pDBData = GetDBData( ScRange(aPos), SC_DB_IMPORT, ScGetDBSelection::Keep ); 278 OSL_ENSURE(pDBData, "Cannot create DB data"); 279 sTarget = pDBData->GetName(); 280 } 281 } 282 } 283 284 // inquire, before old DB range gets overwritten 285 bool bDo = true; 286 if (!bIsNewArea) 287 { 288 OUString aTemplate = ScResId( STR_IMPORT_REPLACE ); 289 OUString aMessage = aTemplate.getToken( 0, '#' ) 290 + sTarget 291 + aTemplate.getToken( 1, '#' ); 292 293 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(nullptr, 294 VclMessageType::Question, VclButtonsType::YesNo, 295 aMessage)); 296 xQueryBox->set_default_response(RET_YES); 297 bDo = xQueryBox->run() == RET_YES; 298 } 299 300 if (bDo) 301 { 302 ScDBDocFunc(*this).UpdateImport( sTarget, aDesc ); 303 rReq.Done(); 304 305 // UpdateImport also updates the internal operations 306 } 307 else 308 rReq.Ignore(); 309 310 if ( bMakeArea && bUndo) 311 GetUndoManager()->LeaveListAction(); 312 } 313 else 314 { 315 OSL_FAIL( "arguments expected" ); 316 } 317 } 318 break; 319 320 case SID_CHART_SOURCE: 321 case SID_CHART_ADDSOURCE: 322 if (pReqArgs) 323 { 324 ScDocument& rDoc = GetDocument(); 325 const SfxPoolItem* pItem; 326 OUString aChartName, aRangeName; 327 328 ScRange aSingleRange; 329 ScRangeListRef aRangeListRef; 330 bool bMultiRange = false; 331 332 bool bColHeaders = true; 333 bool bRowHeaders = true; 334 bool bColInit = false; 335 bool bRowInit = false; 336 bool bAddRange = (nSlot == SID_CHART_ADDSOURCE); 337 338 if( pReqArgs->HasItem( SID_CHART_NAME, &pItem ) ) 339 aChartName = static_cast<const SfxStringItem*>(pItem)->GetValue(); 340 341 if( pReqArgs->HasItem( SID_CHART_SOURCE, &pItem ) ) 342 aRangeName = static_cast<const SfxStringItem*>(pItem)->GetValue(); 343 344 if( pReqArgs->HasItem( FN_PARAM_1, &pItem ) ) 345 { 346 bColHeaders = static_cast<const SfxBoolItem*>(pItem)->GetValue(); 347 bColInit = true; 348 } 349 if( pReqArgs->HasItem( FN_PARAM_2, &pItem ) ) 350 { 351 bRowHeaders = static_cast<const SfxBoolItem*>(pItem)->GetValue(); 352 bRowInit = true; 353 } 354 355 ScAddress::Details aDetails(rDoc.GetAddressConvention(), 0, 0); 356 bool bValid = (aSingleRange.ParseAny(aRangeName, &rDoc, aDetails) & ScRefFlags::VALID) == ScRefFlags::ZERO; 357 if (!bValid) 358 { 359 aRangeListRef = new ScRangeList; 360 aRangeListRef->Parse( aRangeName, &rDoc ); 361 if ( !aRangeListRef->empty() ) 362 { 363 bMultiRange = true; 364 aSingleRange = aRangeListRef->front(); // for header 365 bValid = true; 366 } 367 else 368 aRangeListRef.clear(); 369 } 370 371 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 372 if (pViewSh && bValid && !aChartName.isEmpty() ) 373 { 374 weld::Window* pParent = pViewSh->GetFrameWeld(); 375 376 SCCOL nCol1 = aSingleRange.aStart.Col(); 377 SCROW nRow1 = aSingleRange.aStart.Row(); 378 SCCOL nCol2 = aSingleRange.aEnd.Col(); 379 SCROW nRow2 = aSingleRange.aEnd.Row(); 380 SCTAB nTab = aSingleRange.aStart.Tab(); 381 382 //! limit always or not at all ??? 383 if (!bMultiRange) 384 m_aDocument.LimitChartArea( nTab, nCol1,nRow1, nCol2,nRow2 ); 385 386 // Dialog for column/row headers 387 bool bOk = true; 388 if ( !bAddRange && ( !bColInit || !bRowInit ) ) 389 { 390 ScChartPositioner aChartPositioner( &m_aDocument, nTab, nCol1,nRow1, nCol2,nRow2 ); 391 if (!bColInit) 392 bColHeaders = aChartPositioner.HasColHeaders(); 393 if (!bRowInit) 394 bRowHeaders = aChartPositioner.HasRowHeaders(); 395 396 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); 397 398 ScopedVclPtr<AbstractScColRowLabelDlg> pDlg(pFact->CreateScColRowLabelDlg(pParent, bRowHeaders, bColHeaders)); 399 if ( pDlg->Execute() == RET_OK ) 400 { 401 bColHeaders = pDlg->IsRow(); 402 bRowHeaders = pDlg->IsCol(); 403 404 rReq.AppendItem(SfxBoolItem(FN_PARAM_1, bColHeaders)); 405 rReq.AppendItem(SfxBoolItem(FN_PARAM_2, bRowHeaders)); 406 } 407 else 408 bOk = false; 409 } 410 411 if (bOk) // execute 412 { 413 if (bMultiRange) 414 { 415 if (bUndo) 416 { 417 GetUndoManager()->AddUndoAction( 418 std::make_unique<ScUndoChartData>( this, aChartName, aRangeListRef, 419 bColHeaders, bRowHeaders, bAddRange ) ); 420 } 421 m_aDocument.UpdateChartArea( aChartName, aRangeListRef, 422 bColHeaders, bRowHeaders, bAddRange ); 423 } 424 else 425 { 426 ScRange aNewRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab ); 427 if (bUndo) 428 { 429 GetUndoManager()->AddUndoAction( 430 std::make_unique<ScUndoChartData>( this, aChartName, aNewRange, 431 bColHeaders, bRowHeaders, bAddRange ) ); 432 } 433 m_aDocument.UpdateChartArea( aChartName, aNewRange, 434 bColHeaders, bRowHeaders, bAddRange ); 435 } 436 } 437 } 438 else 439 { 440 OSL_FAIL("UpdateChartArea: no ViewShell or wrong data"); 441 } 442 rReq.Done(); 443 } 444 else 445 { 446 OSL_FAIL("SID_CHART_SOURCE without arguments"); 447 } 448 break; 449 450 case FID_AUTO_CALC: 451 { 452 bool bNewVal; 453 const SfxPoolItem* pItem; 454 if ( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( nSlot, true, &pItem ) ) 455 bNewVal = static_cast<const SfxBoolItem*>(pItem)->GetValue(); 456 else 457 bNewVal = !m_aDocument.GetAutoCalc(); // Toggle for menu 458 m_aDocument.SetAutoCalc( bNewVal ); 459 SetDocumentModified(); 460 if (pBindings) 461 { 462 pBindings->Invalidate( FID_AUTO_CALC ); 463 } 464 rReq.AppendItem( SfxBoolItem( FID_AUTO_CALC, bNewVal ) ); 465 rReq.Done(); 466 } 467 break; 468 case FID_RECALC: 469 DoRecalc( rReq.IsAPI() ); 470 rReq.Done(); 471 break; 472 case FID_HARD_RECALC: 473 DoHardRecalc(); 474 rReq.Done(); 475 break; 476 case SID_UPDATETABLINKS: 477 { 478 ScLkUpdMode nSet = GetLinkUpdateModeState(); 479 480 if (nSet == LM_ALWAYS) 481 { 482 ReloadAllLinks(); 483 rReq.Done(); 484 } 485 else if (nSet == LM_NEVER) 486 { 487 getEmbeddedObjectContainer().setUserAllowsLinkUpdate(false); 488 rReq.Ignore(); 489 } 490 else if (nSet == LM_ON_DEMAND) 491 { 492 ScTabViewShell* pViewSh = GetBestViewShell(); 493 SfxViewFrame* pViewFrame = pViewSh ? pViewSh->GetFrame() : nullptr; 494 if (pViewFrame) 495 { 496 pViewFrame->RemoveInfoBar("enablecontent"); 497 auto pInfoBar = pViewFrame->AppendInfoBar("enablecontent", "", ScResId(STR_RELOAD_TABLES), InfobarType::WARNING); 498 if (pInfoBar) 499 { 500 VclPtrInstance<PushButton> xBtn(&pViewFrame->GetWindow()); 501 xBtn->SetText(ScResId(STR_ENABLE_CONTENT)); 502 xBtn->SetSizePixel(xBtn->GetOptimalSize()); 503 xBtn->SetClickHdl(LINK(this, ScDocShell, ReloadAllLinksHdl)); 504 pInfoBar->addButton(xBtn); 505 } 506 } 507 rReq.Done(); 508 } 509 } 510 break; 511 512 case SID_REIMPORT_AFTER_LOAD: 513 { 514 // Is called after loading if there are DB areas with omitted data 515 516 bool bDone = false; 517 ScDBCollection* pDBColl = m_aDocument.GetDBCollection(); 518 519 if ((m_nCanUpdate != css::document::UpdateDocMode::NO_UPDATE) && 520 (m_nCanUpdate != css::document::UpdateDocMode::QUIET_UPDATE)) 521 { 522 ScRange aRange; 523 ScTabViewShell* pViewSh = GetBestViewShell(); 524 OSL_ENSURE(pViewSh,"SID_REIMPORT_AFTER_LOAD: no View"); 525 if (pViewSh && pDBColl) 526 { 527 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetActiveDialogParent(), 528 VclMessageType::Question, VclButtonsType::YesNo, 529 ScResId(STR_REIMPORT_AFTER_LOAD))); 530 xQueryBox->set_default_response(RET_YES); 531 if (xQueryBox->run() == RET_YES) 532 { 533 ScDBCollection::NamedDBs& rDBs = pDBColl->getNamedDBs(); 534 for (const auto& rxDB : rDBs) 535 { 536 ScDBData& rDBData = *rxDB; 537 if ( rDBData.IsStripData() && 538 rDBData.HasImportParam() && !rDBData.HasImportSelection() ) 539 { 540 rDBData.GetArea(aRange); 541 pViewSh->MarkRange(aRange); 542 543 // Import and internal operations like SID_REFRESH_DBAREA 544 // (inquiry for import not needed here) 545 546 ScImportParam aImportParam; 547 rDBData.GetImportParam( aImportParam ); 548 bool bContinue = pViewSh->ImportData( aImportParam ); 549 rDBData.SetImportParam( aImportParam ); 550 551 // mark (size may have changed) 552 rDBData.GetArea(aRange); 553 pViewSh->MarkRange(aRange); 554 555 if ( bContinue ) // error at import -> abort 556 { 557 // internal operations, if some where saved 558 559 if ( rDBData.HasQueryParam() || rDBData.HasSortParam() || 560 rDBData.HasSubTotalParam() ) 561 pViewSh->RepeatDB(); 562 563 // pivot tables, which have the range as source data 564 565 RefreshPivotTables(aRange); 566 } 567 } 568 } 569 bDone = true; 570 } 571 } 572 } 573 574 if ( !bDone && pDBColl ) 575 { 576 // if not, but then update the dependent formulas 577 //! also for individual ranges, which cannot be updated 578 579 m_aDocument.CalcAll(); //! only for the dependent 580 PostDataChanged(); 581 } 582 583 if (bDone) 584 rReq.Done(); 585 else 586 rReq.Ignore(); 587 } 588 break; 589 590 case SID_AUTO_STYLE: 591 OSL_FAIL("use ScAutoStyleHint instead of SID_AUTO_STYLE"); 592 break; 593 594 case SID_GET_COLORLIST: 595 { 596 const SvxColorListItem* pColItem = GetItem(SID_COLOR_TABLE); 597 const XColorListRef& pList = pColItem->GetColorList(); 598 rReq.SetReturnValue(OfaRefItem<XColorList>(SID_GET_COLORLIST, pList)); 599 } 600 break; 601 602 case FID_CHG_RECORD: 603 { 604 ScDocument& rDoc = GetDocument(); 605 // get argument (recorded macro) 606 const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FID_CHG_RECORD); 607 bool bDo = true; 608 609 // desired state 610 ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack(); 611 bool bActivateTracking = (pChangeTrack == nullptr); // toggle 612 if ( pItem ) 613 bActivateTracking = pItem->GetValue(); // from argument 614 615 if ( !bActivateTracking ) 616 { 617 if ( !pItem ) 618 { 619 // no dialog on playing the macro 620 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(), 621 VclMessageType::Warning, VclButtonsType::YesNo, 622 ScResId(STR_END_REDLINING))); 623 xWarn->set_default_response(RET_NO); 624 bDo = (xWarn->run() == RET_YES ); 625 } 626 627 if ( bDo ) 628 { 629 if (pChangeTrack) 630 { 631 if ( pChangeTrack->IsProtected() ) 632 bDo = ExecuteChangeProtectionDialog(); 633 } 634 if ( bDo ) 635 { 636 rDoc.EndChangeTracking(); 637 PostPaintGridAll(); 638 } 639 } 640 } 641 else 642 { 643 rDoc.StartChangeTracking(); 644 ScChangeViewSettings aChangeViewSet; 645 aChangeViewSet.SetShowChanges(true); 646 rDoc.SetChangeViewSettings(aChangeViewSet); 647 } 648 649 if ( bDo ) 650 { 651 UpdateAcceptChangesDialog(); 652 653 // invalidate slots 654 if (pBindings) 655 pBindings->InvalidateAll(false); 656 if ( !pItem ) 657 rReq.AppendItem( SfxBoolItem( FID_CHG_RECORD, bActivateTracking ) ); 658 rReq.Done(); 659 } 660 else 661 rReq.Ignore(); 662 } 663 break; 664 665 case SID_CHG_PROTECT : 666 { 667 if ( ExecuteChangeProtectionDialog() ) 668 { 669 rReq.Done(); 670 SetDocumentModified(); 671 } 672 else 673 rReq.Ignore(); 674 } 675 break; 676 677 case SID_DOCUMENT_MERGE: 678 case SID_DOCUMENT_COMPARE: 679 { 680 bool bDo = true; 681 ScChangeTrack* pChangeTrack = m_aDocument.GetChangeTrack(); 682 if ( pChangeTrack && !m_pImpl->bIgnoreLostRedliningWarning ) 683 { 684 if ( nSlot == SID_DOCUMENT_COMPARE ) 685 { //! old changes trace will be lost 686 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(), 687 VclMessageType::Warning, VclButtonsType::YesNo, 688 ScResId(STR_END_REDLINING))); 689 xWarn->set_default_response(RET_NO); 690 if (xWarn->run() == RET_YES) 691 bDo = ExecuteChangeProtectionDialog( true ); 692 else 693 bDo = false; 694 } 695 else // merge might reject some actions 696 bDo = ExecuteChangeProtectionDialog( true ); 697 } 698 if ( !bDo ) 699 { 700 rReq.Ignore(); 701 break; 702 } 703 SfxApplication* pApp = SfxGetpApp(); 704 const SfxPoolItem* pItem; 705 const SfxStringItem* pStringItem(nullptr); 706 SfxMedium* pMed = nullptr; 707 if (pReqArgs && pReqArgs->GetItemState(SID_FILE_NAME, true, &pItem) == SfxItemState::SET) 708 { 709 pStringItem = dynamic_cast<const SfxStringItem*>(pItem); 710 } 711 if (pStringItem) 712 { 713 OUString aFileName = pStringItem->GetValue(); 714 715 OUString aFilterName; 716 pStringItem = nullptr; 717 if (pReqArgs->GetItemState(SID_FILTER_NAME, true, &pItem) == SfxItemState::SET) 718 pStringItem = dynamic_cast<const SfxStringItem*>(pItem); 719 if (pStringItem) 720 { 721 aFilterName = pStringItem->GetValue(); 722 } 723 OUString aOptions; 724 pStringItem = nullptr; 725 if (pReqArgs->GetItemState(SID_FILE_FILTEROPTIONS, true, &pItem) == SfxItemState::SET) 726 pStringItem = dynamic_cast<const SfxStringItem*>(pItem); 727 if (pStringItem) 728 { 729 aOptions = pStringItem->GetValue(); 730 } 731 short nVersion = 0; 732 const SfxInt16Item* pInt16Item(nullptr); 733 if (pReqArgs->GetItemState(SID_VERSION, true, &pItem) == SfxItemState::SET) 734 pInt16Item = dynamic_cast<const SfxInt16Item*>(pItem); 735 if (pInt16Item) 736 { 737 nVersion = pInt16Item->GetValue(); 738 } 739 740 // no filter specified -> detection 741 if (aFilterName.isEmpty()) 742 ScDocumentLoader::GetFilterName( aFileName, aFilterName, aOptions, true, false ); 743 744 // filter name from dialog contains application prefix, 745 // GetFilter needs name without the prefix. 746 ScDocumentLoader::RemoveAppPrefix( aFilterName ); 747 748 std::shared_ptr<const SfxFilter> pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( aFilterName ); 749 std::unique_ptr<SfxItemSet> pSet(new SfxAllItemSet( pApp->GetPool() )); 750 if (!aOptions.isEmpty()) 751 pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) ); 752 if ( nVersion != 0 ) 753 pSet->Put( SfxInt16Item( SID_VERSION, nVersion ) ); 754 pMed = new SfxMedium( aFileName, StreamMode::STD_READ, pFilter, std::move(pSet) ); 755 } 756 else 757 { 758 const sfx2::DocumentInserter::Mode mode { nSlot==SID_DOCUMENT_COMPARE 759 ? sfx2::DocumentInserter::Mode::Compare 760 : sfx2::DocumentInserter::Mode::Merge}; 761 // start file dialog asynchronous 762 m_pImpl->bIgnoreLostRedliningWarning = true; 763 m_pImpl->pRequest.reset(new SfxRequest( rReq )); 764 m_pImpl->pDocInserter.reset(); 765 766 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 767 weld::Window* pParent = pViewSh ? pViewSh->GetFrameWeld() : nullptr; 768 m_pImpl->pDocInserter.reset( new ::sfx2::DocumentInserter(pParent, 769 ScDocShell::Factory().GetFactoryName(), mode ) ); 770 m_pImpl->pDocInserter->StartExecuteModal( LINK( this, ScDocShell, DialogClosedHdl ) ); 771 return ; 772 } 773 774 // now execute in earnest... 775 SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() ); 776 777 // pOtherDocSh->DoClose() will be called explicitly later, but it is still more safe to use SfxObjectShellLock here 778 ScDocShell* pOtherDocSh = new ScDocShell; 779 SfxObjectShellLock aDocShTablesRef = pOtherDocSh; 780 pOtherDocSh->DoLoad( pMed ); 781 ErrCode nErr = pOtherDocSh->GetErrorCode(); 782 if (nErr) 783 ErrorHandler::HandleError( nErr ); // also warnings 784 785 if ( !pOtherDocSh->GetError() ) // only errors 786 { 787 bool bHadTrack = ( m_aDocument.GetChangeTrack() != nullptr ); 788 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT 789 sal_uLong nStart = 0; 790 if ( nSlot == SID_DOCUMENT_MERGE && pChangeTrack ) 791 { 792 nStart = pChangeTrack->GetActionMax() + 1; 793 } 794 #endif 795 if ( nSlot == SID_DOCUMENT_COMPARE ) 796 CompareDocument( pOtherDocSh->GetDocument() ); 797 else 798 MergeDocument( pOtherDocSh->GetDocument() ); 799 800 // show "accept changes" dialog 801 //! get view for this document! 802 if ( !IsDocShared() ) 803 { 804 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 805 if ( pViewFrm ) 806 { 807 pViewFrm->ShowChildWindow( ScAcceptChgDlgWrapper::GetChildWindowId() ); //@51669 808 } 809 if ( pBindings ) 810 { 811 pBindings->Invalidate( FID_CHG_ACCEPT ); 812 } 813 } 814 815 rReq.SetReturnValue( SfxInt32Item( nSlot, 0 ) ); //! ??????? 816 rReq.Done(); 817 818 if (!bHadTrack) // newly turned on -> show as well 819 { 820 ScChangeViewSettings* pOldSet = m_aDocument.GetChangeViewSettings(); 821 if ( !pOldSet || !pOldSet->ShowChanges() ) 822 { 823 ScChangeViewSettings aChangeViewSet; 824 aChangeViewSet.SetShowChanges(true); 825 m_aDocument.SetChangeViewSettings(aChangeViewSet); 826 } 827 } 828 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT 829 else if ( nSlot == SID_DOCUMENT_MERGE && IsDocShared() && pChangeTrack ) 830 { 831 sal_uLong nEnd = pChangeTrack->GetActionMax(); 832 if ( nEnd >= nStart ) 833 { 834 // only show changes from merged document 835 ScChangeViewSettings aChangeViewSet; 836 aChangeViewSet.SetShowChanges( true ); 837 aChangeViewSet.SetShowAccepted( true ); 838 aChangeViewSet.SetHasActionRange(); 839 aChangeViewSet.SetTheActionRange( nStart, nEnd ); 840 m_aDocument.SetChangeViewSettings( aChangeViewSet ); 841 842 // update view 843 PostPaintExtras(); 844 PostPaintGridAll(); 845 } 846 } 847 #endif 848 } 849 pOtherDocSh->DoClose(); // delete happens with the Ref 850 } 851 break; 852 853 case SID_DELETE_SCENARIO: 854 if (pReqArgs) 855 { 856 const SfxPoolItem* pItem; 857 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET ) 858 { 859 if (const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>(pItem)) 860 { 861 const OUString& aName = pStringItem->GetValue(); 862 SCTAB nTab; 863 if (m_aDocument.GetTable( aName, nTab )) 864 { 865 // move DeleteTable from viewfunc to docfunc! 866 867 ScTabViewShell* pSh = GetBestViewShell(); 868 if ( pSh ) 869 { 870 //! omit SetTabNo in DeleteTable? 871 SCTAB nDispTab = pSh->GetViewData().GetTabNo(); 872 pSh->DeleteTable( nTab ); 873 pSh->SetTabNo(nDispTab); 874 rReq.Done(); 875 } 876 } 877 } 878 } 879 } 880 break; 881 882 case SID_EDIT_SCENARIO: 883 { 884 const SfxPoolItem* pItem; 885 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET ) 886 { 887 if (const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>(pItem)) 888 { 889 OUString aName = pStringItem->GetValue(); 890 SCTAB nTab; 891 if (m_aDocument.GetTable( aName, nTab )) 892 { 893 if (m_aDocument.IsScenario(nTab)) 894 { 895 OUString aComment; 896 Color aColor; 897 ScScenarioFlags nFlags; 898 m_aDocument.GetScenarioData( nTab, aComment, aColor, nFlags ); 899 900 // Determine if the Sheet that the Scenario was created on 901 // is protected. But first we need to find that Sheet. 902 // Rewind back to the actual sheet. 903 SCTAB nActualTab = nTab; 904 do 905 { 906 nActualTab--; 907 } 908 while(m_aDocument.IsScenario(nActualTab)); 909 bool bSheetProtected = m_aDocument.IsTabProtected(nActualTab); 910 911 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); 912 913 ScopedVclPtr<AbstractScNewScenarioDlg> pNewDlg(pFact->CreateScNewScenarioDlg(GetActiveDialogParent(), aName, true, bSheetProtected)); 914 pNewDlg->SetScenarioData( aName, aComment, aColor, nFlags ); 915 if ( pNewDlg->Execute() == RET_OK ) 916 { 917 pNewDlg->GetScenarioData( aName, aComment, aColor, nFlags ); 918 ModifyScenario( nTab, aName, aComment, aColor, nFlags ); 919 rReq.Done(); 920 } 921 } 922 } 923 } 924 } 925 } 926 break; 927 928 case SID_ATTR_YEAR2000 : 929 { 930 const SfxPoolItem* pItem; 931 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET ) 932 { 933 if (const SfxUInt16Item* pInt16Item = dynamic_cast<const SfxUInt16Item*>(pItem)) 934 { 935 sal_uInt16 nY2k = pInt16Item->GetValue(); 936 // set always to DocOptions, so that it is also saved for S050 937 // (and all inquiries run up until now on it as well). 938 // SetDocOptions propagates that to the NumberFormatter 939 ScDocOptions aDocOpt( m_aDocument.GetDocOptions() ); 940 aDocOpt.SetYear2000( nY2k ); 941 m_aDocument.SetDocOptions( aDocOpt ); 942 // the FormShell shall notice it as well 943 ScTabViewShell* pSh = GetBestViewShell(); 944 if ( pSh ) 945 { 946 FmFormShell* pFSh = pSh->GetFormShell(); 947 if ( pFSh ) 948 pFSh->SetY2KState( nY2k ); 949 } 950 } 951 } 952 } 953 break; 954 955 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT 956 case SID_SHARE_DOC: 957 { 958 ScViewData* pViewData = GetViewData(); 959 if ( !pViewData ) 960 { 961 rReq.Ignore(); 962 break; 963 } 964 965 weld::Window* pWin = GetActiveDialogParent(); 966 ScShareDocumentDlg aDlg(pWin, pViewData); 967 if (aDlg.run() == RET_OK) 968 { 969 bool bSetShared = aDlg.IsShareDocumentChecked(); 970 if ( bSetShared != IsDocShared() ) 971 { 972 if ( bSetShared ) 973 { 974 bool bContinue = true; 975 if ( HasName() ) 976 { 977 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pWin, 978 VclMessageType::Question, VclButtonsType::YesNo, 979 ScResId(STR_DOC_WILLBESAVED))); 980 xQueryBox->set_default_response(RET_YES); 981 if (xQueryBox->run() == RET_NO) 982 { 983 bContinue = false; 984 } 985 } 986 if ( bContinue ) 987 { 988 EnableSharedSettings( true ); 989 990 SC_MOD()->SetInSharedDocSaving( true ); 991 if ( !SwitchToShared( true, true ) ) 992 { 993 // TODO/LATER: what should be done in case the switch has failed? 994 // for example in case the user has cancelled the saveAs operation 995 } 996 997 SC_MOD()->SetInSharedDocSaving( false ); 998 999 InvalidateName(); 1000 GetUndoManager()->Clear(); 1001 1002 ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() ); 1003 if ( pTabView ) 1004 { 1005 pTabView->UpdateLayerLocks(); 1006 } 1007 } 1008 } 1009 else 1010 { 1011 uno::Reference< frame::XModel > xModel; 1012 try 1013 { 1014 // load shared file 1015 xModel.set( LoadSharedDocument(), uno::UNO_SET_THROW ); 1016 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW ); 1017 1018 // check if shared flag is set in shared file 1019 bool bShared = false; 1020 ScModelObj* pDocObj = comphelper::getUnoTunnelImplementation<ScModelObj>( xModel ); 1021 if ( pDocObj ) 1022 { 1023 ScDocShell* pDocShell = dynamic_cast< ScDocShell* >( pDocObj->GetEmbeddedObject() ); 1024 if ( pDocShell ) 1025 { 1026 bShared = pDocShell->HasSharedXMLFlagSet(); 1027 } 1028 } 1029 1030 // #i87870# check if shared status was disabled and enabled again 1031 bool bOwnEntry = false; 1032 try 1033 { 1034 ::svt::ShareControlFile aControlFile( GetSharedFileURL() ); 1035 bOwnEntry = aControlFile.HasOwnEntry(); 1036 } 1037 catch ( uno::Exception& ) 1038 { 1039 } 1040 1041 if ( bShared && bOwnEntry ) 1042 { 1043 uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW ); 1044 if ( xStorable->isReadonly() ) 1045 { 1046 xCloseable->close( true ); 1047 1048 OUString aUserName( ScResId( STR_UNKNOWN_USER ) ); 1049 try 1050 { 1051 ::svt::DocumentLockFile aLockFile( GetSharedFileURL() ); 1052 LockFileEntry aData = aLockFile.GetLockData(); 1053 if ( !aData[LockFileComponent::OOOUSERNAME].isEmpty() ) 1054 { 1055 aUserName = aData[LockFileComponent::OOOUSERNAME]; 1056 } 1057 else if ( !aData[LockFileComponent::SYSUSERNAME].isEmpty() ) 1058 { 1059 aUserName = aData[LockFileComponent::SYSUSERNAME]; 1060 } 1061 } 1062 catch ( uno::Exception& ) 1063 { 1064 } 1065 OUString aMessage( ScResId( STR_FILE_LOCKED_TRY_LATER ) ); 1066 aMessage = aMessage.replaceFirst( "%1", aUserName ); 1067 1068 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pWin, 1069 VclMessageType::Warning, VclButtonsType::Ok, 1070 aMessage)); 1071 xWarn->run(); 1072 } 1073 else 1074 { 1075 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pWin, 1076 VclMessageType::Warning, VclButtonsType::YesNo, 1077 ScResId(STR_DOC_DISABLESHARED))); 1078 xWarn->set_default_response(RET_YES); 1079 1080 if (xWarn->run() == RET_YES) 1081 { 1082 xCloseable->close( true ); 1083 1084 if ( !SwitchToShared( false, true ) ) 1085 { 1086 // TODO/LATER: what should be done in case the switch has failed? 1087 // for example in case the user has cancelled the saveAs operation 1088 } 1089 1090 EnableSharedSettings( false ); 1091 1092 if ( pBindings ) 1093 { 1094 pBindings->ExecuteSynchron( SID_SAVEDOC ); 1095 } 1096 1097 ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() ); 1098 if ( pTabView ) 1099 { 1100 pTabView->UpdateLayerLocks(); 1101 } 1102 } 1103 else 1104 { 1105 xCloseable->close( true ); 1106 } 1107 } 1108 } 1109 else 1110 { 1111 xCloseable->close( true ); 1112 std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pWin, 1113 VclMessageType::Warning, VclButtonsType::Ok, 1114 ScResId(STR_DOC_NOLONGERSHARED))); 1115 xWarn->run(); 1116 } 1117 } 1118 catch ( uno::Exception& ) 1119 { 1120 OSL_FAIL( "SID_SHARE_DOC: caught exception" ); 1121 SC_MOD()->SetInSharedDocSaving( false ); 1122 1123 try 1124 { 1125 uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW ); 1126 xClose->close( true ); 1127 } 1128 catch ( uno::Exception& ) 1129 { 1130 } 1131 } 1132 } 1133 } 1134 } 1135 rReq.Done(); 1136 } 1137 break; 1138 #endif 1139 case SID_OPEN_CALC: 1140 { 1141 SfxStringItem aApp(SID_DOC_SERVICE, "com.sun.star.sheet.SpreadsheetDocument"); 1142 SfxStringItem aTarget(SID_TARGETNAME, "_blank"); 1143 GetViewData()->GetDispatcher().ExecuteList( 1144 SID_OPENDOC, SfxCallMode::API|SfxCallMode::SYNCHRON, 1145 { &aApp, &aTarget }); 1146 } 1147 break; 1148 case SID_NOTEBOOKBAR: 1149 { 1150 const SfxStringItem* pFile = rReq.GetArg<SfxStringItem>( SID_NOTEBOOKBAR ); 1151 1152 if ( pBindings && sfx2::SfxNotebookBar::IsActive() ) 1153 sfx2::SfxNotebookBar::ExecMethod(*pBindings, pFile ? pFile->GetValue() : ""); 1154 else if ( pBindings ) 1155 sfx2::SfxNotebookBar::CloseMethod(*pBindings); 1156 } 1157 break; 1158 case SID_LANGUAGE_STATUS: 1159 { 1160 sal_Int32 nPos = 0; 1161 OUString aLangText; 1162 const SfxStringItem* pItem = rReq.GetArg<SfxStringItem>(nSlot); 1163 if ( pItem ) 1164 aLangText = pItem->GetValue(); 1165 1166 if ( !aLangText.isEmpty() ) 1167 { 1168 LanguageType eLang, eLatin, eCjk, eCtl; 1169 const OUString aDocLangPrefix("Default_"); 1170 const OUString aNoLang("LANGUAGE_NONE"); 1171 const OUString aResetLang("RESET_LANGUAGES"); 1172 1173 ScDocument& rDoc = GetDocument(); 1174 rDoc.GetLanguage( eLatin, eCjk, eCtl ); 1175 1176 if ( aLangText == "*" ) 1177 { 1178 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); 1179 ScTabViewShell* pSh = GetBestViewShell(); 1180 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog(pSh ? pSh->GetDialogParent() : nullptr, SID_LANGUAGE_OPTIONS)); 1181 pDlg->Execute(); 1182 1183 rDoc.GetLanguage( eLang, eCjk, eCtl ); 1184 } 1185 else if ( (nPos = aLangText.indexOf(aDocLangPrefix)) != -1 ) 1186 { 1187 aLangText = aLangText.replaceAt(nPos, aDocLangPrefix.getLength(), ""); 1188 1189 if ( aLangText == aNoLang ) 1190 { 1191 eLang = LANGUAGE_NONE; 1192 rDoc.SetLanguage( eLang, eCjk, eCtl ); 1193 } 1194 else if ( aLangText == aResetLang ) 1195 { 1196 bool bAutoSpell; 1197 1198 ScModule::GetSpellSettings(eLang, eCjk, eCtl, bAutoSpell); 1199 rDoc.SetLanguage(eLang, eCjk, eCtl); 1200 } 1201 else 1202 { 1203 eLang = SvtLanguageTable::GetLanguageType( aLangText ); 1204 if ( eLang != LANGUAGE_DONTKNOW && SvtLanguageOptions::GetScriptTypeOfLanguage(eLang) == SvtScriptType::LATIN ) 1205 { 1206 rDoc.SetLanguage( eLang, eCjk, eCtl ); 1207 } 1208 else 1209 { 1210 eLang = eLatin; 1211 } 1212 } 1213 } 1214 1215 if ( eLang != eLatin ) 1216 { 1217 if ( ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell() ) 1218 { 1219 ScInputHandler* pInputHandler = SC_MOD()->GetInputHdl(pViewSh); 1220 if ( pInputHandler ) 1221 pInputHandler->UpdateSpellSettings(); 1222 1223 pViewSh->UpdateDrawTextOutliner(); 1224 } 1225 1226 SetDocumentModified(); 1227 Broadcast(SfxHint(SfxHintId::LanguageChanged)); 1228 PostPaintGridAll(); 1229 } 1230 } 1231 } 1232 break; 1233 default: 1234 { 1235 // small (?) hack -> forwarding of the slots to TabViewShell 1236 ScTabViewShell* pSh = GetBestViewShell(); 1237 if ( pSh ) 1238 pSh->Execute( rReq ); 1239 #if HAVE_FEATURE_SCRIPTING 1240 else 1241 SbxBase::SetError( ERRCODE_BASIC_NO_ACTIVE_OBJECT ); 1242 #endif 1243 } 1244 } 1245 } 1246 1247 void UpdateAcceptChangesDialog() 1248 { 1249 // update "accept changes" dialog 1250 //! notify all views 1251 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 1252 if ( pViewFrm && pViewFrm->HasChildWindow( FID_CHG_ACCEPT ) ) 1253 { 1254 SfxChildWindow* pChild = pViewFrm->GetChildWindow( FID_CHG_ACCEPT ); 1255 if ( pChild ) 1256 static_cast<ScAcceptChgDlgWrapper*>(pChild)->ReInitDlg(); 1257 } 1258 } 1259 1260 bool ScDocShell::ExecuteChangeProtectionDialog( bool bJustQueryIfProtected ) 1261 { 1262 bool bDone = false; 1263 ScChangeTrack* pChangeTrack = m_aDocument.GetChangeTrack(); 1264 if ( pChangeTrack ) 1265 { 1266 bool bProtected = pChangeTrack->IsProtected(); 1267 if ( bJustQueryIfProtected && !bProtected ) 1268 return true; 1269 1270 OUString aTitle( ScResId( bProtected ? SCSTR_CHG_UNPROTECT : SCSTR_CHG_PROTECT ) ); 1271 OUString aText( ScResId( SCSTR_PASSWORD ) ); 1272 OUString aPassword; 1273 1274 weld::Window* pWin = ScDocShell::GetActiveDialogParent(); 1275 SfxPasswordDialog aDlg(pWin, &aText); 1276 aDlg.set_title(aTitle); 1277 aDlg.SetMinLen(1); 1278 aDlg.set_help_id(GetStaticInterface()->GetSlot(SID_CHG_PROTECT)->GetCommand()); 1279 aDlg.SetEditHelpId( HID_CHG_PROTECT ); 1280 if ( !bProtected ) 1281 aDlg.ShowExtras(SfxShowExtras::CONFIRM); 1282 if (aDlg.run() == RET_OK) 1283 aPassword = aDlg.GetPassword(); 1284 1285 if (!aPassword.isEmpty()) 1286 { 1287 if ( bProtected ) 1288 { 1289 if ( SvPasswordHelper::CompareHashPassword(pChangeTrack->GetProtection(), aPassword) ) 1290 { 1291 if ( bJustQueryIfProtected ) 1292 bDone = true; 1293 else 1294 pChangeTrack->SetProtection( 1295 css::uno::Sequence< sal_Int8 > (0) ); 1296 } 1297 else 1298 { 1299 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pWin, 1300 VclMessageType::Info, VclButtonsType::Ok, 1301 ScResId(SCSTR_WRONGPASSWORD))); 1302 xInfoBox->run(); 1303 } 1304 } 1305 else 1306 { 1307 css::uno::Sequence< sal_Int8 > aPass; 1308 SvPasswordHelper::GetHashPassword( aPass, aPassword ); 1309 pChangeTrack->SetProtection( aPass ); 1310 } 1311 if ( bProtected != pChangeTrack->IsProtected() ) 1312 { 1313 UpdateAcceptChangesDialog(); 1314 bDone = true; 1315 } 1316 } 1317 } 1318 else if ( bJustQueryIfProtected ) 1319 bDone = true; 1320 return bDone; 1321 } 1322 1323 void ScDocShell::DoRecalc( bool bApi ) 1324 { 1325 ScDocShellRecalcGuard aGuard(m_aDocument); 1326 bool bDone = false; 1327 ScTabViewShell* pSh = GetBestViewShell(); 1328 ScInputHandler* pHdl = ( pSh ? SC_MOD()->GetInputHdl( pSh ) : nullptr ); 1329 if ( pSh ) 1330 { 1331 if ( pHdl && pHdl->IsInputMode() && pHdl->IsFormulaMode() && !bApi ) 1332 { 1333 pHdl->FormulaPreview(); // partial result as QuickHelp 1334 bDone = true; 1335 } 1336 else 1337 { 1338 ScTabView::UpdateInputLine(); // InputEnterHandler 1339 pSh->UpdateInputHandler(); 1340 } 1341 } 1342 if (!bDone) // otherwise re-calculate document 1343 { 1344 weld::WaitObject aWaitObj( GetActiveDialogParent() ); 1345 if ( pHdl ) 1346 { 1347 // tdf97897 set current cell to Dirty to force recalculation of cell 1348 ScFormulaCell* pFC = m_aDocument.GetFormulaCell( pHdl->GetCursorPos()); 1349 if (pFC) 1350 pFC->SetDirty(); 1351 } 1352 m_aDocument.CalcFormulaTree(); 1353 if ( pSh ) 1354 pSh->UpdateCharts(true); 1355 1356 m_aDocument.BroadcastUno( SfxHint( SfxHintId::DataChanged ) ); 1357 1358 // If there are charts, then paint everything, so that PostDataChanged 1359 // and the charts do not come one after the other and parts are painted twice. 1360 1361 ScChartListenerCollection* pCharts = m_aDocument.GetChartListenerCollection(); 1362 if ( pCharts && pCharts->hasListeners() ) 1363 PostPaintGridAll(); 1364 else 1365 PostDataChanged(); 1366 } 1367 } 1368 1369 void ScDocShell::DoHardRecalc() 1370 { 1371 auto start = std::chrono::steady_clock::now(); 1372 ScDocShellRecalcGuard aGuard(m_aDocument); 1373 weld::WaitObject aWaitObj( GetActiveDialogParent() ); 1374 ScTabViewShell* pSh = GetBestViewShell(); 1375 if ( pSh ) 1376 { 1377 ScTabView::UpdateInputLine(); // InputEnterHandler 1378 pSh->UpdateInputHandler(); 1379 } 1380 m_aDocument.CalcAll(); 1381 GetDocFunc().DetectiveRefresh(); // creates own Undo 1382 if ( pSh ) 1383 pSh->UpdateCharts(true); 1384 1385 // set notification flags for "calculate" event (used in SfxHintId::DataChanged broadcast) 1386 // (might check for the presence of any formulas on each sheet) 1387 SCTAB nTabCount = m_aDocument.GetTableCount(); 1388 if (m_aDocument.HasAnySheetEventScript( ScSheetEventId::CALCULATE, true )) // search also for VBA handler 1389 for (SCTAB nTab=0; nTab<nTabCount; nTab++) 1390 m_aDocument.SetCalcNotification(nTab); 1391 1392 // CalcAll doesn't broadcast value changes, so SfxHintId::ScCalcAll is broadcasted globally 1393 // in addition to SfxHintId::DataChanged. 1394 m_aDocument.BroadcastUno( SfxHint( SfxHintId::ScCalcAll ) ); 1395 m_aDocument.BroadcastUno( SfxHint( SfxHintId::DataChanged ) ); 1396 1397 // use hard recalc also to disable stream-copying of all sheets 1398 // (somewhat consistent with charts) 1399 for (SCTAB nTab=0; nTab<nTabCount; nTab++) 1400 m_aDocument.SetStreamValid(nTab, false); 1401 1402 PostPaintGridAll(); 1403 auto end = std::chrono::steady_clock::now(); 1404 SAL_INFO("sc.timing", "ScDocShell::DoHardRecalc(): took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms"); 1405 } 1406 1407 void ScDocShell::DoAutoStyle( const ScRange& rRange, const OUString& rStyle ) 1408 { 1409 ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); 1410 ScStyleSheet* pStyleSheet = 1411 pStylePool->FindCaseIns( rStyle, SfxStyleFamily::Para ); 1412 if (!pStyleSheet) 1413 pStyleSheet = static_cast<ScStyleSheet*>( 1414 pStylePool->Find( ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Para )); 1415 if (pStyleSheet) 1416 { 1417 OSL_ENSURE(rRange.aStart.Tab() == rRange.aEnd.Tab(), 1418 "DoAutoStyle with several tables"); 1419 SCTAB nTab = rRange.aStart.Tab(); 1420 SCCOL nStartCol = rRange.aStart.Col(); 1421 SCROW nStartRow = rRange.aStart.Row(); 1422 SCCOL nEndCol = rRange.aEnd.Col(); 1423 SCROW nEndRow = rRange.aEnd.Row(); 1424 m_aDocument.ApplyStyleAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, *pStyleSheet ); 1425 m_aDocument.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab ); 1426 PostPaint( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, PaintPartFlags::Grid ); 1427 } 1428 } 1429 1430 void ScDocShell::NotifyStyle( const SfxStyleSheetHint& rHint ) 1431 { 1432 SfxHintId nId = rHint.GetId(); 1433 const SfxStyleSheetBase* pStyle = rHint.GetStyleSheet(); 1434 if (!pStyle) 1435 return; 1436 1437 if ( pStyle->GetFamily() == SfxStyleFamily::Page ) 1438 { 1439 if ( nId == SfxHintId::StyleSheetModified ) 1440 { 1441 ScDocShellModificator aModificator( *this ); 1442 1443 const OUString& aNewName = pStyle->GetName(); 1444 OUString aOldName = aNewName; 1445 const SfxStyleSheetModifiedHint* pExtendedHint = dynamic_cast<const SfxStyleSheetModifiedHint*>(&rHint); // name changed? 1446 if (pExtendedHint) 1447 aOldName = pExtendedHint->GetOldName(); 1448 1449 if ( aNewName != aOldName ) 1450 m_aDocument.RenamePageStyleInUse( aOldName, aNewName ); 1451 1452 SCTAB nTabCount = m_aDocument.GetTableCount(); 1453 for (SCTAB nTab=0; nTab<nTabCount; nTab++) 1454 if (m_aDocument.GetPageStyle(nTab) == aNewName) // already adjusted to new 1455 { 1456 m_aDocument.PageStyleModified( nTab, aNewName ); 1457 ScPrintFunc aPrintFunc( this, GetPrinter(), nTab ); 1458 aPrintFunc.UpdatePages(); 1459 } 1460 1461 aModificator.SetDocumentModified(); 1462 1463 if (pExtendedHint) 1464 { 1465 SfxBindings* pBindings = GetViewBindings(); 1466 if (pBindings) 1467 { 1468 pBindings->Invalidate( SID_STATUS_PAGESTYLE ); 1469 pBindings->Invalidate( SID_STYLE_FAMILY4 ); 1470 pBindings->Invalidate( FID_RESET_PRINTZOOM ); 1471 pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT ); 1472 pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT ); 1473 } 1474 } 1475 } 1476 } 1477 else if ( pStyle->GetFamily() == SfxStyleFamily::Para ) 1478 { 1479 if ( nId == SfxHintId::StyleSheetModified) 1480 { 1481 const OUString& aNewName = pStyle->GetName(); 1482 OUString aOldName = aNewName; 1483 const SfxStyleSheetModifiedHint* pExtendedHint = dynamic_cast<const SfxStyleSheetModifiedHint*>(&rHint); 1484 if (pExtendedHint) 1485 aOldName = pExtendedHint->GetOldName(); 1486 if ( aNewName != aOldName ) 1487 { 1488 for(SCTAB i = 0; i < m_aDocument.GetTableCount(); ++i) 1489 { 1490 ScConditionalFormatList* pList = m_aDocument.GetCondFormList(i); 1491 if (pList) 1492 pList->RenameCellStyle( aOldName,aNewName ); 1493 } 1494 } 1495 } 1496 } 1497 1498 // everything else goes via slots... 1499 } 1500 1501 // like in printfun.cxx 1502 #define ZOOM_MIN 10 1503 1504 void ScDocShell::SetPrintZoom( SCTAB nTab, sal_uInt16 nScale, sal_uInt16 nPages ) 1505 { 1506 OUString aStyleName = m_aDocument.GetPageStyle( nTab ); 1507 ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); 1508 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SfxStyleFamily::Page ); 1509 OSL_ENSURE( pStyleSheet, "PageStyle not found" ); 1510 if ( pStyleSheet ) 1511 { 1512 ScDocShellModificator aModificator( *this ); 1513 1514 SfxItemSet& rSet = pStyleSheet->GetItemSet(); 1515 const bool bUndo(m_aDocument.IsUndoEnabled()); 1516 if (bUndo) 1517 { 1518 sal_uInt16 nOldScale = rSet.Get(ATTR_PAGE_SCALE).GetValue(); 1519 sal_uInt16 nOldPages = rSet.Get(ATTR_PAGE_SCALETOPAGES).GetValue(); 1520 GetUndoManager()->AddUndoAction( std::make_unique<ScUndoPrintZoom>( 1521 this, nTab, nOldScale, nOldPages, nScale, nPages ) ); 1522 } 1523 1524 rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nScale ) ); 1525 rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, nPages ) ); 1526 1527 ScPrintFunc aPrintFunc( this, GetPrinter(), nTab ); 1528 aPrintFunc.UpdatePages(); 1529 aModificator.SetDocumentModified(); 1530 1531 SfxBindings* pBindings = GetViewBindings(); 1532 if (pBindings) 1533 pBindings->Invalidate( FID_RESET_PRINTZOOM ); 1534 } 1535 } 1536 1537 bool ScDocShell::AdjustPrintZoom( const ScRange& rRange ) 1538 { 1539 bool bChange = false; 1540 SCTAB nTab = rRange.aStart.Tab(); 1541 1542 OUString aStyleName = m_aDocument.GetPageStyle( nTab ); 1543 ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); 1544 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SfxStyleFamily::Page ); 1545 OSL_ENSURE( pStyleSheet, "PageStyle not found" ); 1546 if ( pStyleSheet ) 1547 { 1548 SfxItemSet& rSet = pStyleSheet->GetItemSet(); 1549 bool bHeaders = rSet.Get(ATTR_PAGE_HEADERS).GetValue(); 1550 sal_uInt16 nOldScale = rSet.Get(ATTR_PAGE_SCALE).GetValue(); 1551 sal_uInt16 nOldPages = rSet.Get(ATTR_PAGE_SCALETOPAGES).GetValue(); 1552 const ScRange* pRepeatCol = m_aDocument.GetRepeatColRange( nTab ); 1553 const ScRange* pRepeatRow = m_aDocument.GetRepeatRowRange( nTab ); 1554 1555 // calculate needed scaling for selection 1556 1557 sal_uInt16 nNewScale = nOldScale; 1558 1559 long nBlkTwipsX = 0; 1560 if (bHeaders) 1561 nBlkTwipsX += long(PRINT_HEADER_WIDTH); 1562 SCCOL nStartCol = rRange.aStart.Col(); 1563 SCCOL nEndCol = rRange.aEnd.Col(); 1564 if ( pRepeatCol && nStartCol >= pRepeatCol->aStart.Col() ) 1565 { 1566 for (SCCOL i=pRepeatCol->aStart.Col(); i<=pRepeatCol->aEnd.Col(); i++ ) 1567 nBlkTwipsX += m_aDocument.GetColWidth( i, nTab ); 1568 if ( nStartCol <= pRepeatCol->aEnd.Col() ) 1569 nStartCol = pRepeatCol->aEnd.Col() + 1; 1570 } 1571 // legacy compilers' own scope for i 1572 { 1573 for ( SCCOL i=nStartCol; i<=nEndCol; i++ ) 1574 nBlkTwipsX += m_aDocument.GetColWidth( i, nTab ); 1575 } 1576 1577 long nBlkTwipsY = 0; 1578 if (bHeaders) 1579 nBlkTwipsY += long(PRINT_HEADER_HEIGHT); 1580 SCROW nStartRow = rRange.aStart.Row(); 1581 SCROW nEndRow = rRange.aEnd.Row(); 1582 if ( pRepeatRow && nStartRow >= pRepeatRow->aStart.Row() ) 1583 { 1584 nBlkTwipsY += m_aDocument.GetRowHeight( pRepeatRow->aStart.Row(), 1585 pRepeatRow->aEnd.Row(), nTab ); 1586 if ( nStartRow <= pRepeatRow->aEnd.Row() ) 1587 nStartRow = pRepeatRow->aEnd.Row() + 1; 1588 } 1589 nBlkTwipsY += m_aDocument.GetRowHeight( nStartRow, nEndRow, nTab ); 1590 1591 Size aPhysPage; 1592 long nHdr, nFtr; 1593 ScPrintFunc aOldPrFunc( this, GetPrinter(), nTab ); 1594 aOldPrFunc.GetScaleData( aPhysPage, nHdr, nFtr ); 1595 nBlkTwipsY += nHdr + nFtr; 1596 1597 if ( nBlkTwipsX == 0 ) // hidden columns/rows may lead to 0 1598 nBlkTwipsX = 1; 1599 if ( nBlkTwipsY == 0 ) 1600 nBlkTwipsY = 1; 1601 1602 long nNeeded = std::min( aPhysPage.Width() * 100 / nBlkTwipsX, 1603 aPhysPage.Height() * 100 / nBlkTwipsY ); 1604 if ( nNeeded < ZOOM_MIN ) 1605 nNeeded = ZOOM_MIN; // boundary 1606 if ( nNeeded < static_cast<long>(nNewScale) ) 1607 nNewScale = static_cast<sal_uInt16>(nNeeded); 1608 1609 bChange = ( nNewScale != nOldScale || nOldPages != 0 ); 1610 if ( bChange ) 1611 SetPrintZoom( nTab, nNewScale, 0 ); 1612 } 1613 return bChange; 1614 } 1615 1616 void ScDocShell::PageStyleModified( const OUString& rStyleName, bool bApi ) 1617 { 1618 ScDocShellModificator aModificator( *this ); 1619 1620 SCTAB nTabCount = m_aDocument.GetTableCount(); 1621 SCTAB nUseTab = MAXTAB+1; 1622 for (SCTAB nTab=0; nTab<nTabCount && nUseTab>MAXTAB; nTab++) 1623 if ( m_aDocument.GetPageStyle(nTab) == rStyleName && 1624 ( !bApi || m_aDocument.GetPageSize(nTab).Width() ) ) 1625 nUseTab = nTab; 1626 // at bApi only if breaks already shown 1627 1628 if (ValidTab(nUseTab)) // not used -> nothing to do 1629 { 1630 bool bWarn = false; 1631 1632 ScPrintFunc aPrintFunc( this, GetPrinter(), nUseTab ); //! cope without CountPages 1633 if (!aPrintFunc.UpdatePages()) // sets breaks on all tabs 1634 bWarn = true; 1635 1636 if (bWarn && !bApi) 1637 { 1638 weld::Window* pWin = GetActiveDialogParent(); 1639 weld::WaitObject aWaitOff(pWin); 1640 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pWin, 1641 VclMessageType::Info, VclButtonsType::Ok, 1642 ScResId(STR_PRINT_INVALID_AREA))); 1643 xInfoBox->run(); 1644 } 1645 } 1646 1647 aModificator.SetDocumentModified(); 1648 1649 SfxBindings* pBindings = GetViewBindings(); 1650 if (pBindings) 1651 { 1652 pBindings->Invalidate( FID_RESET_PRINTZOOM ); 1653 pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT ); 1654 pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT ); 1655 } 1656 } 1657 1658 void ScDocShell::ExecutePageStyle( const SfxViewShell& rCaller, 1659 SfxRequest& rReq, 1660 SCTAB nCurTab ) 1661 { 1662 const SfxItemSet* pReqArgs = rReq.GetArgs(); 1663 1664 switch ( rReq.GetSlot() ) 1665 { 1666 case SID_STATUS_PAGESTYLE: // click on StatusBar control 1667 case SID_FORMATPAGE: 1668 { 1669 if ( pReqArgs == nullptr ) 1670 { 1671 OUString aOldName = m_aDocument.GetPageStyle( nCurTab ); 1672 ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); 1673 SfxStyleSheetBase* pStyleSheet 1674 = pStylePool->Find( aOldName, SfxStyleFamily::Page ); 1675 1676 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" ); 1677 1678 if ( pStyleSheet ) 1679 { 1680 ScStyleSaveData aOldData; 1681 const bool bUndo(m_aDocument.IsUndoEnabled()); 1682 if (bUndo) 1683 aOldData.InitFromStyle( pStyleSheet ); 1684 1685 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet(); 1686 rStyleSet.MergeRange( XATTR_FILL_FIRST, XATTR_FILL_LAST ); 1687 1688 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); 1689 1690 VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScStyleDlg(GetActiveDialogParent(), *pStyleSheet, true)); 1691 1692 std::shared_ptr<SfxRequest> pRequest(new SfxRequest(rReq)); 1693 rReq.Ignore(); // the 'old' request is not relevant any more 1694 pDlg->StartExecuteAsync([this, pDlg, pRequest, pStyleSheet, aOldData, aOldName, &rStyleSet, nCurTab, &rCaller, bUndo](sal_Int32 nResult){ 1695 if ( nResult == RET_OK ) 1696 { 1697 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); 1698 1699 weld::WaitObject aWait( GetActiveDialogParent() ); 1700 1701 OUString aNewName = pStyleSheet->GetName(); 1702 if ( aNewName != aOldName && 1703 m_aDocument.RenamePageStyleInUse( aOldName, aNewName ) ) 1704 { 1705 SfxBindings* pBindings = GetViewBindings(); 1706 if (pBindings) 1707 { 1708 pBindings->Invalidate( SID_STATUS_PAGESTYLE ); 1709 pBindings->Invalidate( FID_RESET_PRINTZOOM ); 1710 } 1711 } 1712 1713 if ( pOutSet ) 1714 m_aDocument.ModifyStyleSheet( *pStyleSheet, *pOutSet ); 1715 1716 // memorizing for GetState(): 1717 GetPageOnFromPageStyleSet( &rStyleSet, nCurTab, m_bHeaderOn, m_bFooterOn ); 1718 rCaller.GetViewFrame()->GetBindings().Invalidate( SID_HFEDIT ); 1719 1720 ScStyleSaveData aNewData; 1721 aNewData.InitFromStyle( pStyleSheet ); 1722 if (bUndo) 1723 { 1724 GetUndoManager()->AddUndoAction( 1725 std::make_unique<ScUndoModifyStyle>( this, SfxStyleFamily::Page, 1726 aOldData, aNewData ) ); 1727 } 1728 1729 PageStyleModified( aNewName, false ); 1730 pRequest->Done(); 1731 } 1732 pDlg->disposeOnce(); 1733 }); 1734 } 1735 } 1736 } 1737 break; 1738 1739 case SID_HFEDIT: 1740 { 1741 if ( pReqArgs == nullptr ) 1742 { 1743 OUString aStr( m_aDocument.GetPageStyle( nCurTab ) ); 1744 1745 ScStyleSheetPool* pStylePool 1746 = m_aDocument.GetStyleSheetPool(); 1747 1748 SfxStyleSheetBase* pStyleSheet 1749 = pStylePool->Find( aStr, SfxStyleFamily::Page ); 1750 1751 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" ); 1752 1753 if ( pStyleSheet ) 1754 { 1755 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet(); 1756 1757 SvxPageUsage eUsage = rStyleSet.Get( ATTR_PAGE ).GetPageUsage(); 1758 bool bShareHeader = rStyleSet 1759 .Get(ATTR_PAGE_HEADERSET) 1760 .GetItemSet() 1761 .Get(ATTR_PAGE_SHARED) 1762 .GetValue(); 1763 bool bShareFooter = rStyleSet 1764 .Get(ATTR_PAGE_FOOTERSET) 1765 .GetItemSet() 1766 .Get(ATTR_PAGE_SHARED) 1767 .GetValue(); 1768 sal_uInt16 nResId = 0; 1769 1770 switch ( eUsage ) 1771 { 1772 case SvxPageUsage::Left: 1773 case SvxPageUsage::Right: 1774 { 1775 if ( m_bHeaderOn && m_bFooterOn ) 1776 nResId = RID_SCDLG_HFEDIT; 1777 else if ( SvxPageUsage::Right == eUsage ) 1778 { 1779 if ( !m_bHeaderOn && m_bFooterOn ) 1780 nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER; 1781 else if ( m_bHeaderOn && !m_bFooterOn ) 1782 nResId = RID_SCDLG_HFEDIT_RIGHTHEADER; 1783 } 1784 else 1785 { 1786 // #69193a# respect "shared" setting 1787 if ( !m_bHeaderOn && m_bFooterOn ) 1788 nResId = bShareFooter ? 1789 RID_SCDLG_HFEDIT_RIGHTFOOTER : 1790 RID_SCDLG_HFEDIT_LEFTFOOTER; 1791 else if ( m_bHeaderOn && !m_bFooterOn ) 1792 nResId = bShareHeader ? 1793 RID_SCDLG_HFEDIT_RIGHTHEADER : 1794 RID_SCDLG_HFEDIT_LEFTHEADER; 1795 } 1796 } 1797 break; 1798 1799 case SvxPageUsage::Mirror: 1800 case SvxPageUsage::All: 1801 default: 1802 { 1803 if ( !bShareHeader && !bShareFooter ) 1804 { 1805 if ( m_bHeaderOn && m_bFooterOn ) 1806 nResId = RID_SCDLG_HFEDIT_ALL; 1807 else if ( !m_bHeaderOn && m_bFooterOn ) 1808 nResId = RID_SCDLG_HFEDIT_FOOTER; 1809 else if ( m_bHeaderOn && !m_bFooterOn ) 1810 nResId = RID_SCDLG_HFEDIT_HEADER; 1811 } 1812 else if ( bShareHeader && bShareFooter ) 1813 { 1814 if ( m_bHeaderOn && m_bFooterOn ) 1815 nResId = RID_SCDLG_HFEDIT; 1816 else 1817 { 1818 if ( !m_bHeaderOn && m_bFooterOn ) 1819 nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER; 1820 else if ( m_bHeaderOn && !m_bFooterOn ) 1821 nResId = RID_SCDLG_HFEDIT_RIGHTHEADER; 1822 } 1823 } 1824 else if ( !bShareHeader && bShareFooter ) 1825 { 1826 if ( m_bHeaderOn && m_bFooterOn ) 1827 nResId = RID_SCDLG_HFEDIT_SFTR; 1828 else if ( !m_bHeaderOn && m_bFooterOn ) 1829 nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER; 1830 else if ( m_bHeaderOn && !m_bFooterOn ) 1831 nResId = RID_SCDLG_HFEDIT_HEADER; 1832 } 1833 else if ( bShareHeader && !bShareFooter ) 1834 { 1835 if ( m_bHeaderOn && m_bFooterOn ) 1836 nResId = RID_SCDLG_HFEDIT_SHDR; 1837 else if ( !m_bHeaderOn && m_bFooterOn ) 1838 nResId = RID_SCDLG_HFEDIT_FOOTER; 1839 else if ( m_bHeaderOn && !m_bFooterOn ) 1840 nResId = RID_SCDLG_HFEDIT_RIGHTHEADER; 1841 } 1842 } 1843 } 1844 1845 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); 1846 1847 VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScHFEditDlg( 1848 GetActiveDialogParent(), 1849 rStyleSet, 1850 aStr, 1851 nResId)); 1852 std::shared_ptr<SfxRequest> xRequest(new SfxRequest(rReq)); 1853 rReq.Ignore(); // the 'old' request is not relevant any more 1854 pDlg->StartExecuteAsync([this, pDlg, pStyleSheet, xRequest](sal_Int32 nResult){ 1855 if ( nResult == RET_OK ) 1856 { 1857 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); 1858 1859 if ( pOutSet ) 1860 m_aDocument.ModifyStyleSheet( *pStyleSheet, *pOutSet ); 1861 1862 SetDocumentModified(); 1863 xRequest->Done(); 1864 } 1865 pDlg->disposeOnce(); 1866 }); 1867 } 1868 } 1869 } 1870 break; 1871 1872 default: 1873 break; 1874 } 1875 } 1876 1877 void ScDocShell::GetStatePageStyle( SfxItemSet& rSet, 1878 SCTAB nCurTab ) 1879 { 1880 SfxWhichIter aIter(rSet); 1881 sal_uInt16 nWhich = aIter.FirstWhich(); 1882 while ( nWhich ) 1883 { 1884 switch (nWhich) 1885 { 1886 case SID_STATUS_PAGESTYLE: 1887 rSet.Put( SfxStringItem( nWhich, m_aDocument.GetPageStyle( nCurTab ) ) ); 1888 break; 1889 1890 case SID_HFEDIT: 1891 { 1892 OUString aStr = m_aDocument.GetPageStyle( nCurTab ); 1893 ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); 1894 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStr, SfxStyleFamily::Page ); 1895 1896 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" ); 1897 1898 if ( pStyleSheet ) 1899 { 1900 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet(); 1901 GetPageOnFromPageStyleSet( &rStyleSet, nCurTab, m_bHeaderOn, m_bFooterOn ); 1902 1903 if ( !m_bHeaderOn && !m_bFooterOn ) 1904 rSet.DisableItem( nWhich ); 1905 } 1906 } 1907 break; 1908 } 1909 1910 nWhich = aIter.NextWhich(); 1911 } 1912 } 1913 1914 void ScDocShell::GetState( SfxItemSet &rSet ) 1915 { 1916 bool bTabView = GetBestViewShell() != nullptr; 1917 1918 SfxWhichIter aIter(rSet); 1919 for (sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich()) 1920 { 1921 if (!bTabView) 1922 { 1923 rSet.DisableItem(nWhich); 1924 continue; 1925 } 1926 1927 switch (nWhich) 1928 { 1929 case FID_AUTO_CALC: 1930 if ( m_aDocument.GetHardRecalcState() != ScDocument::HardRecalcState::OFF ) 1931 rSet.DisableItem( nWhich ); 1932 else 1933 rSet.Put( SfxBoolItem( nWhich, m_aDocument.GetAutoCalc() ) ); 1934 break; 1935 1936 case FID_CHG_RECORD: 1937 if ( IsDocShared() ) 1938 rSet.DisableItem( nWhich ); 1939 else 1940 rSet.Put( SfxBoolItem( nWhich, 1941 m_aDocument.GetChangeTrack() != nullptr ) ); 1942 break; 1943 1944 case SID_CHG_PROTECT: 1945 { 1946 ScChangeTrack* pChangeTrack = m_aDocument.GetChangeTrack(); 1947 if ( pChangeTrack && !IsDocShared() ) 1948 rSet.Put( SfxBoolItem( nWhich, 1949 pChangeTrack->IsProtected() ) ); 1950 else 1951 rSet.DisableItem( nWhich ); 1952 } 1953 break; 1954 1955 case SID_DOCUMENT_COMPARE: 1956 { 1957 if ( IsDocShared() ) 1958 { 1959 rSet.DisableItem( nWhich ); 1960 } 1961 } 1962 break; 1963 1964 // When a formula is edited, FID_RECALC must be enabled in any case. Recalc for 1965 // the doc was disabled once because of a bug if AutoCalc was on, but is now 1966 // always enabled because of another bug. 1967 1968 case SID_TABLES_COUNT: 1969 rSet.Put( SfxInt16Item( nWhich, m_aDocument.GetTableCount() ) ); 1970 break; 1971 1972 case SID_ATTR_YEAR2000 : 1973 rSet.Put( SfxUInt16Item( nWhich, 1974 m_aDocument.GetDocOptions().GetYear2000() ) ); 1975 break; 1976 1977 case SID_SHARE_DOC: 1978 { 1979 if ( IsReadOnly() || GetBestViewShell()->isExportLocked() ) 1980 { 1981 rSet.DisableItem( nWhich ); 1982 } 1983 } 1984 break; 1985 1986 case SID_ATTR_CHAR_FONTLIST: 1987 rSet.Put( SvxFontListItem( m_pImpl->pFontList.get(), nWhich ) ); 1988 break; 1989 1990 case SID_NOTEBOOKBAR: 1991 { 1992 if (GetViewBindings()) 1993 { 1994 bool bVisible = sfx2::SfxNotebookBar::StateMethod(*GetViewBindings(), 1995 "modules/scalc/ui/"); 1996 rSet.Put( SfxBoolItem( SID_NOTEBOOKBAR, bVisible ) ); 1997 } 1998 } 1999 break; 2000 2001 case SID_LANGUAGE_STATUS: 2002 { 2003 LanguageType eLatin, eCjk, eCtl; 2004 2005 GetDocument().GetLanguage( eLatin, eCjk, eCtl ); 2006 OUString sLanguage = SvtLanguageTable::GetLanguageString(eLatin); 2007 if (comphelper::LibreOfficeKit::isActive()) { 2008 if (eLatin == LANGUAGE_NONE) 2009 sLanguage += ";-"; 2010 else 2011 sLanguage += ";" + LanguageTag(eLatin).getBcp47(false); 2012 } 2013 rSet.Put(SfxStringItem(nWhich, sLanguage)); 2014 } 2015 break; 2016 2017 default: 2018 { 2019 } 2020 break; 2021 } 2022 } 2023 } 2024 2025 void ScDocShell::Draw( OutputDevice* pDev, const JobSetup & /* rSetup */, sal_uInt16 nAspect ) 2026 { 2027 2028 SCTAB nVisTab = m_aDocument.GetVisibleTab(); 2029 if (!m_aDocument.HasTable(nVisTab)) 2030 return; 2031 2032 ComplexTextLayoutFlags nOldLayoutMode = pDev->GetLayoutMode(); 2033 pDev->SetLayoutMode( ComplexTextLayoutFlags::Default ); // even if it's the same, to get the metafile action 2034 2035 if ( nAspect == ASPECT_THUMBNAIL ) 2036 { 2037 tools::Rectangle aBoundRect = GetVisArea( ASPECT_THUMBNAIL ); 2038 ScViewData aTmpData( this, nullptr ); 2039 aTmpData.SetTabNo(nVisTab); 2040 SnapVisArea( aBoundRect ); 2041 aTmpData.SetScreen( aBoundRect ); 2042 ScPrintFunc::DrawToDev( &m_aDocument, pDev, 1.0, aBoundRect, &aTmpData, true ); 2043 } 2044 else 2045 { 2046 tools::Rectangle aOldArea = SfxObjectShell::GetVisArea(); 2047 tools::Rectangle aNewArea = aOldArea; 2048 ScViewData aTmpData( this, nullptr ); 2049 aTmpData.SetTabNo(nVisTab); 2050 SnapVisArea( aNewArea ); 2051 if ( aNewArea != aOldArea && (m_aDocument.GetPosLeft() > 0 || m_aDocument.GetPosTop() > 0) ) 2052 SfxObjectShell::SetVisArea( aNewArea ); 2053 aTmpData.SetScreen( aNewArea ); 2054 ScPrintFunc::DrawToDev( &m_aDocument, pDev, 1.0, aNewArea, &aTmpData, true ); 2055 } 2056 2057 pDev->SetLayoutMode( nOldLayoutMode ); 2058 } 2059 2060 tools::Rectangle ScDocShell::GetVisArea( sal_uInt16 nAspect ) const 2061 { 2062 SfxObjectCreateMode eShellMode = GetCreateMode(); 2063 if ( eShellMode == SfxObjectCreateMode::ORGANIZER ) 2064 { 2065 // without contents we also don't know how large are the contents; 2066 // return empty rectangle, it will then be calculated after the loading 2067 return tools::Rectangle(); 2068 } 2069 2070 if( nAspect == ASPECT_THUMBNAIL ) 2071 { 2072 SCTAB nVisTab = m_aDocument.GetVisibleTab(); 2073 if (!m_aDocument.HasTable(nVisTab)) 2074 { 2075 nVisTab = 0; 2076 const_cast<ScDocShell*>(this)->m_aDocument.SetVisibleTab(nVisTab); 2077 } 2078 Size aSize = m_aDocument.GetPageSize(nVisTab); 2079 const long SC_PREVIEW_SIZE_X = 10000; 2080 const long SC_PREVIEW_SIZE_Y = 12400; 2081 tools::Rectangle aArea( 0,0, SC_PREVIEW_SIZE_X, SC_PREVIEW_SIZE_Y); 2082 if (aSize.Width() > aSize.Height()) 2083 { 2084 aArea.SetRight( SC_PREVIEW_SIZE_Y ); 2085 aArea.SetBottom( SC_PREVIEW_SIZE_X ); 2086 } 2087 2088 bool bNegativePage = m_aDocument.IsNegativePage( m_aDocument.GetVisibleTab() ); 2089 if ( bNegativePage ) 2090 ScDrawLayer::MirrorRectRTL( aArea ); 2091 SnapVisArea( aArea ); 2092 return aArea; 2093 } 2094 else if( nAspect == ASPECT_CONTENT && eShellMode != SfxObjectCreateMode::EMBEDDED ) 2095 { 2096 // fetch visarea like after loading 2097 2098 SCTAB nVisTab = m_aDocument.GetVisibleTab(); 2099 if (!m_aDocument.HasTable(nVisTab)) 2100 { 2101 nVisTab = 0; 2102 const_cast<ScDocShell*>(this)->m_aDocument.SetVisibleTab(nVisTab); 2103 } 2104 SCCOL nStartCol; 2105 SCROW nStartRow; 2106 m_aDocument.GetDataStart( nVisTab, nStartCol, nStartRow ); 2107 SCCOL nEndCol; 2108 SCROW nEndRow; 2109 m_aDocument.GetPrintArea( nVisTab, nEndCol, nEndRow ); 2110 if (nStartCol>nEndCol) 2111 nStartCol = nEndCol; 2112 if (nStartRow>nEndRow) 2113 nStartRow = nEndRow; 2114 tools::Rectangle aNewArea = m_aDocument 2115 .GetMMRect( nStartCol,nStartRow, nEndCol,nEndRow, nVisTab ); 2116 //TODO/LATER: different methods for setting VisArea?! 2117 const_cast<ScDocShell*>(this)->SfxObjectShell::SetVisArea( aNewArea ); 2118 return aNewArea; 2119 } 2120 else 2121 return SfxObjectShell::GetVisArea( nAspect ); 2122 } 2123 2124 namespace { 2125 2126 [[nodiscard]] 2127 long SnapHorizontal( const ScDocument& rDoc, SCTAB nTab, long nVal, SCCOL& rStartCol ) 2128 { 2129 SCCOL nCol = 0; 2130 long nTwips = static_cast<long>(nVal / HMM_PER_TWIPS); 2131 long nSnap = 0; 2132 while ( nCol<rDoc.MaxCol() ) 2133 { 2134 long nAdd = rDoc.GetColWidth(nCol, nTab); 2135 if ( nSnap + nAdd/2 < nTwips || nCol < rStartCol ) 2136 { 2137 nSnap += nAdd; 2138 ++nCol; 2139 } 2140 else 2141 break; 2142 } 2143 nVal = static_cast<long>( nSnap * HMM_PER_TWIPS ); 2144 rStartCol = nCol; 2145 return nVal; 2146 } 2147 2148 [[nodiscard]] 2149 long SnapVertical( const ScDocument& rDoc, SCTAB nTab, long nVal, SCROW& rStartRow ) 2150 { 2151 SCROW nRow = 0; 2152 long nTwips = static_cast<long>(nVal / HMM_PER_TWIPS); 2153 long nSnap = 0; 2154 2155 bool bFound = false; 2156 for (SCROW i = nRow; i <= rDoc.MaxRow(); ++i) 2157 { 2158 SCROW nLastRow; 2159 if (rDoc.RowHidden(i, nTab, nullptr, &nLastRow)) 2160 { 2161 i = nLastRow; 2162 continue; 2163 } 2164 2165 nRow = i; 2166 long nAdd = rDoc.GetRowHeight(i, nTab); 2167 if ( nSnap + nAdd/2 < nTwips || nRow < rStartRow ) 2168 { 2169 nSnap += nAdd; 2170 ++nRow; 2171 } 2172 else 2173 { 2174 bFound = true; 2175 break; 2176 } 2177 } 2178 if (!bFound) 2179 nRow = rDoc.MaxRow(); // all hidden down to the bottom 2180 2181 nVal = static_cast<long>( nSnap * HMM_PER_TWIPS ); 2182 rStartRow = nRow; 2183 return nVal; 2184 } 2185 2186 } 2187 2188 void ScDocShell::SnapVisArea( tools::Rectangle& rRect ) const 2189 { 2190 SCTAB nTab = m_aDocument.GetVisibleTab(); 2191 long nOrigTop = rRect.Top(); 2192 long nOrigLeft = rRect.Left(); 2193 bool bNegativePage = m_aDocument.IsNegativePage( nTab ); 2194 if ( bNegativePage ) 2195 ScDrawLayer::MirrorRectRTL( rRect ); // calculate with positive (LTR) values 2196 2197 SCCOL nCol = m_aDocument.GetPosLeft(); 2198 long nSetLeft = SnapHorizontal( m_aDocument, nTab, rRect.Left(), nCol ); 2199 rRect.SetLeft( nSetLeft ); 2200 ++nCol; // at least one column 2201 long nCorrectionLeft = (nOrigLeft == 0 && nCol > 0) ? nSetLeft : 0; // initial correction 2202 rRect.SetRight( SnapHorizontal( m_aDocument, nTab, rRect.Right() + nCorrectionLeft, nCol )); 2203 2204 SCROW nRow = m_aDocument.GetPosTop(); 2205 long nSetTop = SnapVertical( m_aDocument, nTab, rRect.Top(), nRow ); 2206 rRect.SetTop( nSetTop ); 2207 ++nRow; // at least one row 2208 long nCorrectionTop = (nOrigTop == 0 && nRow > 0) ? nSetTop : 0; // initial correction 2209 rRect.SetBottom( SnapVertical( m_aDocument, nTab, rRect.Bottom() + nCorrectionTop, nRow )); 2210 2211 if ( bNegativePage ) 2212 ScDrawLayer::MirrorRectRTL( rRect ); // back to real rectangle 2213 } 2214 2215 void ScDocShell::GetPageOnFromPageStyleSet( const SfxItemSet* pStyleSet, 2216 SCTAB nCurTab, 2217 bool& rbHeader, 2218 bool& rbFooter ) 2219 { 2220 if ( !pStyleSet ) 2221 { 2222 ScStyleSheetPool* pStylePool = m_aDocument.GetStyleSheetPool(); 2223 SfxStyleSheetBase* pStyleSheet = pStylePool-> 2224 Find( m_aDocument.GetPageStyle( nCurTab ), 2225 SfxStyleFamily::Page ); 2226 2227 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" ); 2228 2229 if ( pStyleSheet ) 2230 pStyleSet = &pStyleSheet->GetItemSet(); 2231 else 2232 rbHeader = rbFooter = false; 2233 } 2234 2235 OSL_ENSURE( pStyleSet, "PageStyle-Set not found! :-(" ); 2236 if (!pStyleSet) 2237 return; 2238 2239 const SvxSetItem* pSetItem = nullptr; 2240 const SfxItemSet* pSet = nullptr; 2241 2242 pSetItem = &pStyleSet->Get( ATTR_PAGE_HEADERSET ); 2243 pSet = &pSetItem->GetItemSet(); 2244 rbHeader = pSet->Get(ATTR_PAGE_ON).GetValue(); 2245 2246 pSetItem = &pStyleSet->Get( ATTR_PAGE_FOOTERSET ); 2247 pSet = &pSetItem->GetItemSet(); 2248 rbFooter = pSet->Get(ATTR_PAGE_ON).GetValue(); 2249 } 2250 2251 #if defined(_WIN32) 2252 bool ScDocShell::DdeGetData( const OUString& rItem, 2253 const OUString& rMimeType, 2254 css::uno::Any & rValue ) 2255 { 2256 SotClipboardFormatId eFormatId = SotExchange::GetFormatIdFromMimeType( rMimeType ); 2257 if (SotClipboardFormatId::STRING == eFormatId || SotClipboardFormatId::STRING_TSVC == eFormatId) 2258 { 2259 if( rItem.equalsIgnoreAsciiCase( "Format" ) ) 2260 { 2261 OString aFmtByte(OUStringToOString(m_aDdeTextFmt, 2262 osl_getThreadTextEncoding())); 2263 rValue <<= css::uno::Sequence< sal_Int8 >( 2264 reinterpret_cast<const sal_Int8*>(aFmtByte.getStr()), 2265 aFmtByte.getLength() + 1 ); 2266 return true; 2267 } 2268 ScImportExport aObj( &m_aDocument, rItem ); 2269 if ( !aObj.IsRef() ) 2270 return false; // invalid range 2271 2272 if( m_aDdeTextFmt[0] == 'F' ) 2273 aObj.SetFormulas( true ); 2274 if( m_aDdeTextFmt == "SYLK" || 2275 m_aDdeTextFmt == "FSYLK" ) 2276 { 2277 OString aData; 2278 if( aObj.ExportByteString( aData, osl_getThreadTextEncoding(), 2279 SotClipboardFormatId::SYLK ) ) 2280 { 2281 rValue <<= css::uno::Sequence< sal_Int8 >( 2282 reinterpret_cast<const sal_Int8*>(aData.getStr()), 2283 aData.getLength() + 1 ); 2284 return true; 2285 } 2286 else 2287 return false; 2288 } 2289 if( m_aDdeTextFmt == "CSV" || 2290 m_aDdeTextFmt == "FCSV" ) 2291 aObj.SetSeparator( ',' ); 2292 aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, 0, false ) ); 2293 return aObj.ExportData( rMimeType, rValue ); 2294 } 2295 2296 ScImportExport aObj( &m_aDocument, rItem ); 2297 aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, 0, false ) ); 2298 return aObj.IsRef() && aObj.ExportData( rMimeType, rValue ); 2299 } 2300 2301 bool ScDocShell::DdeSetData( const OUString& rItem, 2302 const OUString& rMimeType, 2303 const css::uno::Any & rValue ) 2304 { 2305 SotClipboardFormatId eFormatId = SotExchange::GetFormatIdFromMimeType( rMimeType ); 2306 if (SotClipboardFormatId::STRING == eFormatId || SotClipboardFormatId::STRING_TSVC == eFormatId) 2307 { 2308 if( rItem.equalsIgnoreAsciiCase( "Format" ) ) 2309 { 2310 if ( ScByteSequenceToString::GetString( m_aDdeTextFmt, rValue, osl_getThreadTextEncoding() ) ) 2311 { 2312 m_aDdeTextFmt = m_aDdeTextFmt.toAsciiUpperCase(); 2313 return true; 2314 } 2315 return false; 2316 } 2317 ScImportExport aObj( &m_aDocument, rItem ); 2318 if( m_aDdeTextFmt[0] == 'F' ) 2319 aObj.SetFormulas( true ); 2320 if( m_aDdeTextFmt == "SYLK" || 2321 m_aDdeTextFmt == "FSYLK" ) 2322 { 2323 OUString aData; 2324 if ( ScByteSequenceToString::GetString( aData, rValue, osl_getThreadTextEncoding() ) ) 2325 { 2326 return aObj.ImportString( aData, SotClipboardFormatId::SYLK ); 2327 } 2328 return false; 2329 } 2330 if( m_aDdeTextFmt == "CSV" || 2331 m_aDdeTextFmt == "FCSV" ) 2332 aObj.SetSeparator( ',' ); 2333 OSL_ENSURE( false, "Implementation is missing" ); 2334 return false; 2335 } 2336 /*ScImportExport aObj( &aDocument, rItem ); 2337 return aObj.IsRef() && ScImportExport::ImportData( rMimeType, rValue );*/ 2338 OSL_ENSURE( false, "Implementation is missing" ); 2339 return false; 2340 } 2341 #endif 2342 2343 ::sfx2::SvLinkSource* ScDocShell::DdeCreateLinkSource( const OUString& rItem ) 2344 { 2345 // only check for valid item string - range is parsed again in ScServerObject ctor 2346 2347 // named range? 2348 OUString aPos = rItem; 2349 ScRangeName* pRange = m_aDocument.GetRangeName(); 2350 if( pRange ) 2351 { 2352 const ScRangeData* pData = pRange->findByUpperName(ScGlobal::pCharClass->uppercase(aPos)); 2353 if (pData) 2354 { 2355 if( pData->HasType( ScRangeData::Type::RefArea ) 2356 || pData->HasType( ScRangeData::Type::AbsArea ) 2357 || pData->HasType( ScRangeData::Type::AbsPos ) ) 2358 pData->GetSymbol( aPos ); // continue with the name's contents 2359 } 2360 } 2361 2362 // Address in DDE function must be always parsed as CONV_OOO so that it 2363 // would always work regardless of current address conversion. We do this 2364 // because the address item in a DDE entry is *not* normalized when saved 2365 // into ODF. 2366 ScRange aRange; 2367 bool bValid = ( (aRange.Parse(aPos, &m_aDocument, formula::FormulaGrammar::CONV_OOO ) & ScRefFlags::VALID) || 2368 (aRange.aStart.Parse(aPos, &m_aDocument, formula::FormulaGrammar::CONV_OOO) & ScRefFlags::VALID) ); 2369 2370 ScServerObject* pObj = nullptr; // NULL = error 2371 if ( bValid ) 2372 pObj = new ScServerObject( this, rItem ); 2373 2374 // GetLinkManager()->InsertServer() is in the ScServerObject ctor 2375 2376 return pObj; 2377 } 2378 2379 void ScDocShell::LOKCommentNotify(LOKCommentNotificationType nType, const ScDocument* pDocument, const ScAddress& rPos, const ScPostIt* pNote) 2380 { 2381 if ( !pDocument->IsDocVisible() || // don't want callbacks until document load 2382 !comphelper::LibreOfficeKit::isActive() || 2383 comphelper::LibreOfficeKit::isTiledAnnotations() ) 2384 return; 2385 2386 boost::property_tree::ptree aAnnotation; 2387 aAnnotation.put("action", (nType == LOKCommentNotificationType::Add ? "Add" : 2388 (nType == LOKCommentNotificationType::Remove ? "Remove" : 2389 (nType == LOKCommentNotificationType::Modify ? "Modify" : "???")))); 2390 2391 assert(pNote); 2392 aAnnotation.put("id", pNote->GetId()); 2393 aAnnotation.put("tab", rPos.Tab()); 2394 2395 if (nType != LOKCommentNotificationType::Remove) 2396 { 2397 aAnnotation.put("author", pNote->GetAuthor()); 2398 aAnnotation.put("dateTime", pNote->GetDate()); 2399 aAnnotation.put("text", pNote->GetText()); 2400 2401 // Calculating the cell cursor position 2402 ScViewData* pViewData = GetViewData(); 2403 if (pViewData && pViewData->GetActiveWin()) 2404 { 2405 Point aScrPos = pViewData->GetScrPos(rPos.Col(), rPos.Row(), pViewData->GetActivePart(), true); 2406 long nSizeXPix; 2407 long nSizeYPix; 2408 pViewData->GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeXPix, nSizeYPix); 2409 2410 const double fPPTX = pViewData->GetPPTX(); 2411 const double fPPTY = pViewData->GetPPTY(); 2412 tools::Rectangle aRect(Point(aScrPos.getX() / fPPTX, aScrPos.getY() / fPPTY), 2413 Size(nSizeXPix / fPPTX, nSizeYPix / fPPTY)); 2414 2415 aAnnotation.put("cellPos", aRect.toString()); 2416 } 2417 } 2418 2419 boost::property_tree::ptree aTree; 2420 aTree.add_child("comment", aAnnotation); 2421 std::stringstream aStream; 2422 boost::property_tree::write_json(aStream, aTree); 2423 std::string aPayload = aStream.str(); 2424 2425 SfxViewShell* pViewShell = SfxViewShell::GetFirst(); 2426 while (pViewShell) 2427 { 2428 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_COMMENT, aPayload.c_str()); 2429 pViewShell = SfxViewShell::GetNext(*pViewShell); 2430 } 2431 } 2432 2433 ScViewData* ScDocShell::GetViewData() 2434 { 2435 SfxViewShell* pCur = SfxViewShell::Current(); 2436 ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell *>( pCur ); 2437 return pViewSh ? &pViewSh->GetViewData() : nullptr; 2438 } 2439 2440 SCTAB ScDocShell::GetCurTab() 2441 { 2442 //! this must be made non-static and use a ViewShell from this document! 2443 2444 ScViewData* pViewData = GetViewData(); 2445 2446 return pViewData ? pViewData->GetTabNo() : static_cast<SCTAB>(0); 2447 } 2448 2449 ScTabViewShell* ScDocShell::GetBestViewShell( bool bOnlyVisible ) 2450 { 2451 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 2452 // wrong Doc? 2453 if( pViewSh && pViewSh->GetViewData().GetDocShell() != this ) 2454 pViewSh = nullptr; 2455 if( !pViewSh ) 2456 { 2457 // 1. find ViewShell 2458 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, bOnlyVisible ); 2459 if( pFrame ) 2460 { 2461 SfxViewShell* p = pFrame->GetViewShell(); 2462 pViewSh = dynamic_cast< ScTabViewShell *>( p ); 2463 } 2464 } 2465 return pViewSh; 2466 } 2467 2468 SfxBindings* ScDocShell::GetViewBindings() 2469 { 2470 // used to invalidate slots after changes to this document 2471 2472 SfxViewShell* pViewSh = GetBestViewShell(); 2473 if (pViewSh) 2474 return &pViewSh->GetViewFrame()->GetBindings(); 2475 else 2476 return nullptr; 2477 } 2478 2479 ScDocShell* ScDocShell::GetShellByNum( sal_uInt16 nDocNo ) // static 2480 { 2481 ScDocShell* pFound = nullptr; 2482 SfxObjectShell* pShell = SfxObjectShell::GetFirst(); 2483 sal_uInt16 nShellCnt = 0; 2484 2485 while ( pShell && !pFound ) 2486 { 2487 if ( dynamic_cast<const ScDocShell*>(pShell) != nullptr ) 2488 { 2489 if ( nShellCnt == nDocNo ) 2490 pFound = static_cast<ScDocShell*>(pShell); 2491 else 2492 ++nShellCnt; 2493 } 2494 pShell = SfxObjectShell::GetNext( *pShell ); 2495 } 2496 2497 return pFound; 2498 } 2499 2500 IMPL_LINK( ScDocShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg, void ) 2501 { 2502 OSL_ENSURE( _pFileDlg, "ScDocShell::DialogClosedHdl(): no file dialog" ); 2503 OSL_ENSURE( m_pImpl->pDocInserter, "ScDocShell::DialogClosedHdl(): no document inserter" ); 2504 2505 if ( ERRCODE_NONE == _pFileDlg->GetError() ) 2506 { 2507 sal_uInt16 nSlot = m_pImpl->pRequest->GetSlot(); 2508 std::unique_ptr<SfxMedium> pMed = m_pImpl->pDocInserter->CreateMedium(); 2509 // #i87094# If a .odt was selected pMed is NULL. 2510 if (pMed) 2511 { 2512 m_pImpl->pRequest->AppendItem( SfxStringItem( SID_FILE_NAME, pMed->GetName() ) ); 2513 if ( SID_DOCUMENT_COMPARE == nSlot ) 2514 { 2515 if ( pMed->GetFilter() ) 2516 m_pImpl->pRequest->AppendItem( 2517 SfxStringItem( SID_FILTER_NAME, pMed->GetFilter()->GetFilterName() ) ); 2518 OUString sOptions = ScDocumentLoader::GetOptions( *pMed ); 2519 if ( !sOptions.isEmpty() ) 2520 m_pImpl->pRequest->AppendItem( SfxStringItem( SID_FILE_FILTEROPTIONS, sOptions ) ); 2521 } 2522 const SfxPoolItem* pItem = nullptr; 2523 const SfxInt16Item* pInt16Item(nullptr); 2524 SfxItemSet* pSet = pMed->GetItemSet(); 2525 if (pSet && pSet->GetItemState(SID_VERSION, true, &pItem) == SfxItemState::SET) 2526 { 2527 pInt16Item = dynamic_cast<const SfxInt16Item*>(pItem); 2528 } 2529 if (pInt16Item) 2530 { 2531 m_pImpl->pRequest->AppendItem( *pItem ); 2532 } 2533 2534 Execute( *(m_pImpl->pRequest) ); 2535 } 2536 } 2537 2538 m_pImpl->bIgnoreLostRedliningWarning = false; 2539 } 2540 2541 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT 2542 2543 void ScDocShell::EnableSharedSettings( bool bEnable ) 2544 { 2545 SetDocumentModified(); 2546 2547 if ( bEnable ) 2548 { 2549 m_aDocument.EndChangeTracking(); 2550 m_aDocument.StartChangeTracking(); 2551 2552 // hide accept or reject changes dialog 2553 sal_uInt16 nId = ScAcceptChgDlgWrapper::GetChildWindowId(); 2554 SfxViewFrame* pViewFrame = SfxViewFrame::Current(); 2555 if ( pViewFrame && pViewFrame->HasChildWindow( nId ) ) 2556 { 2557 pViewFrame->ToggleChildWindow( nId ); 2558 SfxBindings* pBindings = GetViewBindings(); 2559 if ( pBindings ) 2560 { 2561 pBindings->Invalidate( FID_CHG_ACCEPT ); 2562 } 2563 } 2564 } 2565 else 2566 { 2567 m_aDocument.EndChangeTracking(); 2568 } 2569 2570 ScChangeViewSettings aChangeViewSet; 2571 aChangeViewSet.SetShowChanges( false ); 2572 m_aDocument.SetChangeViewSettings( aChangeViewSet ); 2573 } 2574 2575 uno::Reference< frame::XModel > ScDocShell::LoadSharedDocument() 2576 { 2577 uno::Reference< frame::XModel > xModel; 2578 try 2579 { 2580 SC_MOD()->SetInSharedDocLoading( true ); 2581 uno::Reference< frame::XDesktop2 > xLoader = frame::Desktop::create( ::comphelper::getProcessComponentContext() ); 2582 uno::Sequence < beans::PropertyValue > aArgs( 1 ); 2583 aArgs[0].Name = "Hidden"; 2584 aArgs[0].Value <<= true; 2585 2586 if ( GetMedium() ) 2587 { 2588 const SfxStringItem* pPasswordItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_PASSWORD, false); 2589 if ( pPasswordItem && !pPasswordItem->GetValue().isEmpty() ) 2590 { 2591 aArgs.realloc( 2 ); 2592 aArgs[1].Name = "Password"; 2593 aArgs[1].Value <<= pPasswordItem->GetValue(); 2594 } 2595 const SfxUnoAnyItem* pEncryptionItem = SfxItemSet::GetItem<SfxUnoAnyItem>(GetMedium()->GetItemSet(), SID_ENCRYPTIONDATA, false); 2596 if (pEncryptionItem) 2597 { 2598 aArgs.realloc(aArgs.getLength() + 1); 2599 aArgs[aArgs.getLength() - 1].Name = "EncryptionData"; 2600 aArgs[aArgs.getLength() - 1].Value = pEncryptionItem->GetValue(); 2601 } 2602 } 2603 2604 xModel.set( 2605 xLoader->loadComponentFromURL( GetSharedFileURL(), "_blank", 0, aArgs ), 2606 uno::UNO_QUERY_THROW ); 2607 SC_MOD()->SetInSharedDocLoading( false ); 2608 } 2609 catch ( uno::Exception& ) 2610 { 2611 OSL_FAIL( "ScDocShell::LoadSharedDocument(): caught exception" ); 2612 SC_MOD()->SetInSharedDocLoading( false ); 2613 try 2614 { 2615 uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW ); 2616 xClose->close( true ); 2617 return uno::Reference< frame::XModel >(); 2618 } 2619 catch ( uno::Exception& ) 2620 { 2621 return uno::Reference< frame::XModel >(); 2622 } 2623 } 2624 return xModel; 2625 } 2626 2627 #endif 2628 2629 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 2630
