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