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