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 <stdlib.h> 23 #include <hintids.hxx> 24 #include <comphelper/string.hxx> 25 #include <o3tl/any.hxx> 26 #include <officecfg/Office/Common.hxx> 27 #include <vcl/graph.hxx> 28 #include <vcl/inputctx.hxx> 29 #include <svl/eitem.hxx> 30 #include <unotools/configmgr.hxx> 31 #include <unotools/lingucfg.hxx> 32 #include <unotools/useroptions.hxx> 33 #include <sfx2/dispatch.hxx> 34 #include <sfx2/docfile.hxx> 35 #include <sfx2/objface.hxx> 36 #include <sfx2/request.hxx> 37 #include <sfx2/event.hxx> 38 #include <sfx2/infobar.hxx> 39 #include <svx/ruler.hxx> 40 #include <svx/srchdlg.hxx> 41 #include <svx/fmshell.hxx> 42 #include <svx/extrusionbar.hxx> 43 #include <svx/fontworkbar.hxx> 44 #include <svx/fmview.hxx> 45 #include <unotxvw.hxx> 46 #include <cmdid.h> 47 #include <svl/hint.hxx> 48 #include <swmodule.hxx> 49 #include <inputwin.hxx> 50 #include <uivwimp.hxx> 51 #include <edtwin.hxx> 52 #include <textsh.hxx> 53 #include <listsh.hxx> 54 #include <tabsh.hxx> 55 #include <grfsh.hxx> 56 #include <mediash.hxx> 57 #include <docsh.hxx> 58 #include <frmsh.hxx> 59 #include <olesh.hxx> 60 #include <drawsh.hxx> 61 #include <drawbase.hxx> 62 #include <drformsh.hxx> 63 #include <drwtxtsh.hxx> 64 #include <beziersh.hxx> 65 #include <navsh.hxx> 66 #include <globdoc.hxx> 67 #include <scroll.hxx> 68 #include <gloshdl.hxx> 69 #include <usrpref.hxx> 70 #include <srcview.hxx> 71 #include <strings.hrc> 72 #include <doc.hxx> 73 #include <IDocumentUndoRedo.hxx> 74 #include <IDocumentSettingAccess.hxx> 75 #include <IDocumentDrawModelAccess.hxx> 76 #include <DocumentFieldsManager.hxx> 77 #include <IDocumentState.hxx> 78 #include <IDocumentLayoutAccess.hxx> 79 #include <drawdoc.hxx> 80 #include <wdocsh.hxx> 81 #include <wrtsh.hxx> 82 #include <barcfg.hxx> 83 #include <pview.hxx> 84 #include <swdtflvr.hxx> 85 #include <prtopt.hxx> 86 #include <com/sun/star/frame/FrameSearchFlag.hpp> 87 #include <com/sun/star/frame/XLayoutManager.hpp> 88 #include <com/sun/star/scanner/ScannerContext.hpp> 89 #include <com/sun/star/scanner/XScannerManager2.hpp> 90 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 91 #include <com/sun/star/sdb/XDatabaseContext.hpp> 92 #include <com/sun/star/sdb/DatabaseContext.hpp> 93 #include <com/sun/star/sdbc/XDataSource.hpp> 94 #include <toolkit/helper/vclunohelper.hxx> 95 #include <sal/log.hxx> 96 97 #include <formatclipboard.hxx> 98 #include <PostItMgr.hxx> 99 #include <annotsh.hxx> 100 #include <swruler.hxx> 101 102 #include <com/sun/star/document/XDocumentProperties.hpp> 103 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> 104 105 #include <comphelper/propertyvalue.hxx> 106 #include <sfx2/lokhelper.hxx> 107 #include <LibreOfficeKit/LibreOfficeKitEnums.h> 108 #include <svtools/embedhlp.hxx> 109 #include <tools/UnitConversion.hxx> 110 111 using namespace ::com::sun::star; 112 using namespace ::com::sun::star::uno; 113 using namespace ::com::sun::star::lang; 114 using namespace ::com::sun::star::scanner; 115 using namespace ::com::sun::star::sdb; 116 using namespace ::com::sun::star::sdbc; 117 118 #define SWVIEWFLAGS SfxViewShellFlags::HAS_PRINTOPTIONS 119 120 // Statics. OMG. 121 122 bool bDocSzUpdated = true; 123 124 SvxSearchItem* SwView::s_pSrchItem = nullptr; 125 126 bool SwView::s_bExtra = false; 127 bool SwView::s_bFound = false; 128 bool SwView::s_bJustOpened = false; 129 130 std::unique_ptr<SearchAttrItemList> SwView::s_xSearchList; 131 std::unique_ptr<SearchAttrItemList> SwView::s_xReplaceList; 132 133 SfxDispatcher &SwView::GetDispatcher() 134 { 135 return *GetViewFrame()->GetDispatcher(); 136 } 137 138 void SwView::ImpSetVerb( SelectionType nSelType ) 139 { 140 bool bResetVerbs = m_bVerbsActive; 141 if ( !GetViewFrame()->GetFrame().IsInPlace() && 142 (SelectionType::Ole|SelectionType::Graphic) & nSelType ) 143 { 144 if ( m_pWrtShell->IsSelObjProtected(FlyProtectFlags::Content) == FlyProtectFlags::NONE ) 145 { 146 if ( nSelType & SelectionType::Ole ) 147 { 148 SetVerbs( GetWrtShell().GetOLEObject()->getSupportedVerbs() ); 149 m_bVerbsActive = true; 150 bResetVerbs = false; 151 } 152 } 153 } 154 if ( bResetVerbs ) 155 { 156 SetVerbs( Sequence< embed::VerbDescriptor >() ); 157 m_bVerbsActive = false; 158 } 159 } 160 161 // Called by the SwEditWin when it gets the focus. 162 163 void SwView::GotFocus() const 164 { 165 // if we got the focus, and the form shell *is* on the top of the dispatcher 166 // stack, then we need to rebuild the stack (the form shell doesn't belong to 167 // the top then) 168 const SfxDispatcher& rDispatcher = const_cast< SwView* >( this )->GetDispatcher(); 169 SfxShell* pTopShell = rDispatcher.GetShell( 0 ); 170 FmFormShell* pAsFormShell = dynamic_cast<FmFormShell*>( pTopShell ); 171 if ( pAsFormShell ) 172 { 173 pAsFormShell->ForgetActiveControl(); 174 const_cast< SwView* >( this )->AttrChangedNotify(nullptr); 175 } 176 else if ( m_pPostItMgr ) 177 { 178 SwAnnotationShell* pAsAnnotationShell = dynamic_cast<SwAnnotationShell*>( pTopShell ); 179 if ( pAsAnnotationShell ) 180 { 181 m_pPostItMgr->SetActiveSidebarWin(nullptr); 182 const_cast< SwView* >( this )->AttrChangedNotify(nullptr); 183 } 184 } 185 if( GetWrtShellPtr() ) 186 { 187 SwWrtShell& rWrtShell = GetWrtShell(); 188 rWrtShell.GetDoc()->getIDocumentLayoutAccess().SetCurrentViewShell( GetWrtShellPtr() ); 189 rWrtShell.GetDoc()->getIDocumentSettingAccess().set( DocumentSettingId::BROWSE_MODE, 190 rWrtShell.GetViewOptions()->getBrowseMode() ); 191 } 192 } 193 194 // called by the FormShell when a form control is focused. This is 195 // a request to put the form shell on the top of the dispatcher stack 196 197 IMPL_LINK_NOARG(SwView, FormControlActivated, LinkParamNone*, void) 198 { 199 // if a form control has been activated, and the form shell is not on the top 200 // of the dispatcher stack, then we need to activate it 201 const SfxDispatcher& rDispatcher = GetDispatcher(); 202 const SfxShell* pTopShell = rDispatcher.GetShell( 0 ); 203 const FmFormShell* pAsFormShell = dynamic_cast<const FmFormShell*>( pTopShell ); 204 if ( !pAsFormShell ) 205 { 206 // if we're editing text currently, cancel this 207 SdrView *pSdrView = m_pWrtShell ? m_pWrtShell->GetDrawView() : nullptr; 208 if ( pSdrView && pSdrView->IsTextEdit() ) 209 pSdrView->SdrEndTextEdit( true ); 210 211 AttrChangedNotify(nullptr); 212 } 213 } 214 215 IMPL_LINK_NOARG(SwView, ExchangeDatabaseHandler, weld::Button&, void) 216 { 217 GetDispatcher().Execute(FN_CHANGE_DBFIELD); 218 } 219 220 namespace 221 { 222 uno::Reference<frame::XLayoutManager> getLayoutManager(const SfxViewFrame& rViewFrame) 223 { 224 uno::Reference<frame::XLayoutManager> xLayoutManager; 225 uno::Reference<beans::XPropertySet> xPropSet(rViewFrame.GetFrame().GetFrameInterface(), 226 uno::UNO_QUERY); 227 if (xPropSet.is()) 228 { 229 try 230 { 231 xLayoutManager.set(xPropSet->getPropertyValue("LayoutManager"), uno::UNO_QUERY); 232 } 233 catch (const Exception& e) 234 { 235 SAL_WARN("sw.ui", "Failure getting layout manager: " + e.Message); 236 } 237 } 238 return xLayoutManager; 239 } 240 } 241 242 void SwView::ShowUIElement(const OUString& sElementURL) const 243 { 244 if (auto xLayoutManager = getLayoutManager(*GetViewFrame())) 245 { 246 if (!xLayoutManager->getElement(sElementURL).is()) 247 { 248 xLayoutManager->createElement(sElementURL); 249 xLayoutManager->showElement(sElementURL); 250 } 251 } 252 } 253 254 void SwView::SelectShell() 255 { 256 // Attention: Maintain the SelectShell for the WebView additionally 257 258 if(m_bInDtor) 259 return; 260 261 // Decision if the UpdateTable has to be called 262 bool bUpdateTable = false; 263 const SwFrameFormat* pCurTableFormat = m_pWrtShell->GetTableFormat(); 264 if(pCurTableFormat && pCurTableFormat != m_pLastTableFormat) 265 { 266 bUpdateTable = true; // can only be executed later 267 } 268 m_pLastTableFormat = pCurTableFormat; 269 270 //SEL_TBL and SEL_TBL_CELLS can be ORed! 271 SelectionType nNewSelectionType = m_pWrtShell->GetSelectionType() 272 & ~SelectionType::TableCell; 273 274 if ( m_pFormShell && m_pFormShell->IsActiveControl() ) 275 nNewSelectionType |= SelectionType::FormControl; 276 277 if ( nNewSelectionType == m_nSelectionType ) 278 { 279 GetViewFrame()->GetBindings().InvalidateAll( false ); 280 if ( m_nSelectionType & SelectionType::Ole || 281 m_nSelectionType & SelectionType::Graphic ) 282 // For graphs and OLE the verb can be modified of course! 283 ImpSetVerb( nNewSelectionType ); 284 } 285 else 286 { 287 288 SfxDispatcher &rDispatcher = GetDispatcher(); 289 SwToolbarConfigItem *pBarCfg = SW_MOD()->GetToolbarConfig(); 290 291 if ( m_pShell ) 292 { 293 rDispatcher.Flush(); // Really erase all cached shells 294 //Remember to the old selection which toolbar was visible 295 ToolbarId eId = rDispatcher.GetObjectBarId(SFX_OBJECTBAR_OBJECT); 296 if (eId != ToolbarId::None) 297 pBarCfg->SetTopToolbar(m_nSelectionType, eId); 298 299 for ( sal_uInt16 i = 0; true; ++i ) 300 { 301 SfxShell *pSfxShell = rDispatcher.GetShell( i ); 302 if ( dynamic_cast< const SwBaseShell *>( pSfxShell ) != nullptr 303 || dynamic_cast< const SwDrawTextShell *>( pSfxShell ) != nullptr 304 || dynamic_cast< const svx::ExtrusionBar*>( pSfxShell ) != nullptr 305 || dynamic_cast< const svx::FontworkBar*>( pSfxShell ) != nullptr 306 || dynamic_cast< const SwAnnotationShell *>( pSfxShell ) != nullptr 307 ) 308 { 309 rDispatcher.Pop( *pSfxShell, SfxDispatcherPopFlags::POP_DELETE ); 310 } 311 else if ( dynamic_cast< const FmFormShell *>( pSfxShell ) != nullptr ) 312 { 313 rDispatcher.Pop( *pSfxShell ); 314 } 315 else 316 break; 317 } 318 } 319 320 bool bInitFormShell = false; 321 if (!m_pFormShell) 322 { 323 bInitFormShell = true; 324 m_pFormShell = new FmFormShell( this ); 325 m_pFormShell->SetControlActivationHandler( LINK( this, SwView, FormControlActivated ) ); 326 StartListening(*m_pFormShell); 327 } 328 329 bool bSetExtInpCntxt = false; 330 m_nSelectionType = nNewSelectionType; 331 ShellMode eShellMode; 332 333 if ( !( m_nSelectionType & SelectionType::FormControl ) ) 334 rDispatcher.Push( *m_pFormShell ); 335 336 m_pShell = new SwNavigationShell( *this ); 337 rDispatcher.Push( *m_pShell ); 338 339 if ( m_nSelectionType & SelectionType::Ole ) 340 { 341 eShellMode = ShellMode::Object; 342 m_pShell = new SwOleShell( *this ); 343 rDispatcher.Push( *m_pShell ); 344 } 345 else if ( m_nSelectionType & SelectionType::Frame 346 || m_nSelectionType & SelectionType::Graphic) 347 { 348 eShellMode = ShellMode::Frame; 349 m_pShell = new SwFrameShell( *this ); 350 rDispatcher.Push( *m_pShell ); 351 if(m_nSelectionType & SelectionType::Graphic ) 352 { 353 eShellMode = ShellMode::Graphic; 354 m_pShell = new SwGrfShell( *this ); 355 rDispatcher.Push( *m_pShell ); 356 } 357 } 358 else if ( m_nSelectionType & SelectionType::DrawObject ) 359 { 360 eShellMode = ShellMode::Draw; 361 m_pShell = new SwDrawShell( *this ); 362 rDispatcher.Push( *m_pShell ); 363 364 if ( m_nSelectionType & SelectionType::Ornament ) 365 { 366 eShellMode = ShellMode::Bezier; 367 m_pShell = new SwBezierShell( *this ); 368 rDispatcher.Push( *m_pShell ); 369 } 370 #if HAVE_FEATURE_AVMEDIA 371 else if( m_nSelectionType & SelectionType::Media ) 372 { 373 eShellMode = ShellMode::Media; 374 m_pShell = new SwMediaShell( *this ); 375 rDispatcher.Push( *m_pShell ); 376 } 377 #endif 378 if (m_nSelectionType & SelectionType::ExtrudedCustomShape) 379 { 380 eShellMode = ShellMode::ExtrudedCustomShape; 381 m_pShell = new svx::ExtrusionBar(this); 382 rDispatcher.Push( *m_pShell ); 383 } 384 if (m_nSelectionType & SelectionType::FontWork) 385 { 386 eShellMode = ShellMode::FontWork; 387 m_pShell = new svx::FontworkBar(this); 388 rDispatcher.Push( *m_pShell ); 389 } 390 } 391 else if ( m_nSelectionType & SelectionType::DbForm ) 392 { 393 eShellMode = ShellMode::DrawForm; 394 m_pShell = new SwDrawFormShell( *this ); 395 396 rDispatcher.Push( *m_pShell ); 397 } 398 else if ( m_nSelectionType & SelectionType::DrawObjectEditMode ) 399 { 400 bSetExtInpCntxt = true; 401 eShellMode = ShellMode::DrawText; 402 rDispatcher.Push( *(new SwBaseShell( *this )) ); 403 m_pShell = new SwDrawTextShell( *this ); 404 rDispatcher.Push( *m_pShell ); 405 } 406 else if ( m_nSelectionType & SelectionType::PostIt ) 407 { 408 eShellMode = ShellMode::PostIt; 409 m_pShell = new SwAnnotationShell( *this ); 410 rDispatcher.Push( *m_pShell ); 411 } 412 else 413 { 414 bSetExtInpCntxt = true; 415 eShellMode = ShellMode::Text; 416 if ( m_nSelectionType & SelectionType::NumberList ) 417 { 418 eShellMode = ShellMode::ListText; 419 m_pShell = new SwListShell( *this ); 420 rDispatcher.Push( *m_pShell ); 421 } 422 m_pShell = new SwTextShell(*this); 423 rDispatcher.Push( *m_pShell ); 424 if ( m_nSelectionType & SelectionType::Table ) 425 { 426 eShellMode = eShellMode == ShellMode::ListText ? ShellMode::TableListText 427 : ShellMode::TableText; 428 m_pShell = new SwTableShell( *this ); 429 rDispatcher.Push( *m_pShell ); 430 } 431 } 432 433 if ( m_nSelectionType & SelectionType::FormControl ) 434 rDispatcher.Push( *m_pFormShell ); 435 436 m_pViewImpl->SetShellMode(eShellMode); 437 ImpSetVerb( m_nSelectionType ); 438 439 if( !GetDocShell()->IsReadOnly() ) 440 { 441 if( bSetExtInpCntxt && GetWrtShell().HasReadonlySel() ) 442 bSetExtInpCntxt = false; 443 444 InputContext aCntxt( GetEditWin().GetInputContext() ); 445 aCntxt.SetOptions( bSetExtInpCntxt 446 ? (aCntxt.GetOptions() | 447 ( InputContextFlags::Text | 448 InputContextFlags::ExtText )) 449 : (aCntxt.GetOptions() & ~ 450 InputContextFlags( InputContextFlags::Text | 451 InputContextFlags::ExtText )) ); 452 GetEditWin().SetInputContext( aCntxt ); 453 } 454 455 // Show Mail Merge toolbar initially for documents with Database fields 456 if (!m_bInitOnceCompleted 457 && (GetWrtShell().IsAnyDatabaseFieldInDoc() 458 || !GetWrtShell().GetDBData().sDataSource.isEmpty())) 459 ShowUIElement("private:resource/toolbar/mailmerge"); 460 461 // Activate the toolbar to the new selection which also was active last time. 462 // Before a flush () must be, but does not affect the UI according to MBA and 463 // is not a performance problem. 464 // TODO/LATER: maybe now the Flush() command is superfluous?! 465 rDispatcher.Flush(); 466 467 Point aPnt = GetEditWin().OutputToScreenPixel(GetEditWin().GetPointerPosPixel()); 468 aPnt = GetEditWin().PixelToLogic(aPnt); 469 GetEditWin().UpdatePointer(aPnt); 470 471 SdrView* pDView = GetWrtShell().GetDrawView(); 472 if ( bInitFormShell && pDView ) 473 m_pFormShell->SetView(dynamic_cast<FmFormView*>( pDView) ); 474 475 } 476 // Opportune time for the communication with OLE objects? 477 if ( GetDocShell()->GetDoc()->IsOLEPrtNotifyPending() ) 478 GetDocShell()->GetDoc()->PrtOLENotify( false ); 479 480 // now the table-update 481 if(bUpdateTable) 482 m_pWrtShell->UpdateTable(); 483 484 GetViewImpl()->GetUNOObject_Impl()->NotifySelChanged(); 485 486 m_bInitOnceCompleted = true; 487 } 488 489 // Interaction: AttrChangedNotify() and TimeoutHdl. 490 // No Update if actions are still open, since the cursor on the core side 491 // can be somewhere in no man's land. 492 // But since we can no longer supply status and we want instead lock 493 // the dispatcher. 494 495 extern "C" 496 { 497 static int lcl_CmpIds( const void *pFirst, const void *pSecond) 498 { 499 return *static_cast<sal_uInt16 const *>(pFirst) - *static_cast<sal_uInt16 const *>(pSecond); 500 } 501 } 502 503 IMPL_LINK_NOARG(SwView, AttrChangedNotify, LinkParamNone*, void) 504 { 505 if ( GetEditWin().IsChainMode() ) 506 GetEditWin().SetChainMode( false ); 507 508 //Opt: Not if PaintLocked. During unlock a notify will be once more triggered. 509 if( !m_pWrtShell->IsPaintLocked() && !g_bNoInterrupt && 510 GetDocShell()->IsReadOnly() ) 511 CheckReadonlyState(); 512 513 if( !m_pWrtShell->IsPaintLocked() && !g_bNoInterrupt ) 514 CheckReadonlySelection(); 515 516 if( !m_bAttrChgNotified ) 517 { 518 if (m_pWrtShell->ActionPend() || g_bNoInterrupt || 519 GetDispatcher().IsLocked() || //do not confuse the SFX 520 GetViewFrame()->GetBindings().IsInUpdate() )//do not confuse the SFX 521 { 522 m_bAttrChgNotified = true; 523 m_aTimer.Start(); 524 525 const SfxPoolItem *pItem; 526 if ( SfxItemState::SET != GetObjectShell()->GetMedium()->GetItemSet()-> 527 GetItemState( SID_HIDDEN, false, &pItem ) || 528 !static_cast<const SfxBoolItem*>(pItem)->GetValue() ) 529 { 530 GetViewFrame()->GetBindings().ENTERREGISTRATIONS(); 531 m_bAttrChgNotifiedWithRegistrations = true; 532 } 533 534 } 535 else 536 SelectShell(); 537 538 } 539 540 // change ui if cursor is at a SwPostItField 541 if (m_pPostItMgr) 542 { 543 // only perform the code that is needed to determine, if at the 544 // actual cursor position is a post-it field 545 m_pPostItMgr->SetShadowState( m_pWrtShell->GetPostItFieldAtCursor() ); 546 } 547 } 548 549 IMPL_LINK_NOARG(SwView, TimeoutHdl, Timer *, void) 550 { 551 if (m_pWrtShell->ActionPend() || g_bNoInterrupt) 552 { 553 m_aTimer.Start(); 554 return; 555 } 556 557 if ( m_bAttrChgNotifiedWithRegistrations ) 558 { 559 GetViewFrame()->GetBindings().LEAVEREGISTRATIONS(); 560 m_bAttrChgNotifiedWithRegistrations = false; 561 } 562 563 CheckReadonlyState(); 564 CheckReadonlySelection(); 565 566 bool bOldUndo = m_pWrtShell->DoesUndo(); 567 m_pWrtShell->DoUndo( false ); 568 SelectShell(); 569 m_pWrtShell->DoUndo( bOldUndo ); 570 m_bAttrChgNotified = false; 571 GetViewImpl()->GetUNOObject_Impl()->NotifySelChanged(); 572 } 573 574 void SwView::CheckReadonlyState() 575 { 576 SfxDispatcher &rDis = GetDispatcher(); 577 // To be able to recognize if it is already disabled! 578 SfxItemState eStateRO, eStateProtAll; 579 const SfxPoolItem *pItem; 580 // Query the status from a slot which is only known to us. 581 // Otherwise the slot is known from other; like the BasicIde 582 eStateRO = rDis.QueryState( FN_INSERT_BOOKMARK, pItem ); 583 eStateProtAll = rDis.QueryState( FN_EDIT_REGION, pItem ); 584 bool bChgd = false; 585 586 if ( !m_pWrtShell->IsCursorReadonly() ) 587 { 588 static sal_uInt16 aROIds[] = 589 { 590 SID_DELETE, FN_BACKSPACE, FN_SHIFT_BACKSPACE, 591 SID_UNDO, 592 SID_REDO, SID_REPEAT, SID_PASTE, 593 SID_PASTE_UNFORMATTED, FN_PASTE_NESTED_TABLE, FN_TABLE_PASTE_ROW_BEFORE, 594 FN_TABLE_PASTE_COL_BEFORE, SID_PASTE_SPECIAL, SID_SBA_BRW_INSERT, 595 SID_BACKGROUND_COLOR, FN_INSERT_BOOKMARK, SID_CHARMAP_CONTROL, 596 SID_CHARMAP, SID_EMOJI_CONTROL, FN_INSERT_SOFT_HYPHEN, 597 FN_INSERT_HARDHYPHEN, FN_INSERT_HARD_SPACE, FN_INSERT_NNBSP, 598 FN_INSERT_BREAK, FN_INSERT_LINEBREAK, FN_INSERT_COLUMN_BREAK, 599 FN_INSERT_BREAK_DLG, 600 FN_DELETE_SENT, FN_DELETE_BACK_SENT, FN_DELETE_WORD, 601 FN_DELETE_BACK_WORD, FN_DELETE_LINE, FN_DELETE_BACK_LINE, 602 FN_DELETE_PARA, FN_DELETE_BACK_PARA, FN_DELETE_WHOLE_LINE, 603 FN_CALCULATE, FN_FORMAT_RESET, 604 FN_POSTIT, FN_JAVAEDIT, SID_ATTR_PARA_ADJUST_LEFT, 605 SID_ATTR_PARA_ADJUST_RIGHT, SID_ATTR_PARA_ADJUST_CENTER,SID_ATTR_PARA_ADJUST_BLOCK, 606 SID_ATTR_PARA_LINESPACE_10, SID_ATTR_PARA_LINESPACE_15, SID_ATTR_PARA_LINESPACE_20, 607 SID_ATTR_CHAR_FONT, SID_ATTR_CHAR_FONTHEIGHT, SID_ATTR_CHAR_COLOR_BACKGROUND, 608 SID_ATTR_CHAR_COLOR_BACKGROUND_EXT, SID_ATTR_CHAR_COLOR_EXT, 609 SID_ATTR_CHAR_COLOR, SID_ATTR_CHAR_WEIGHT, SID_ATTR_CHAR_POSTURE, 610 SID_ATTR_CHAR_OVERLINE, 611 SID_ATTR_CHAR_UNDERLINE, SID_ATTR_FLASH, SID_ATTR_CHAR_STRIKEOUT, 612 SID_ULINE_VAL_SINGLE, SID_ULINE_VAL_DOUBLE, SID_ULINE_VAL_DOTTED, 613 SID_ATTR_CHAR_CONTOUR, SID_ATTR_CHAR_SHADOWED, 614 SID_ATTR_CHAR_AUTOKERN, SID_ATTR_CHAR_ESCAPEMENT, FN_SET_SUPER_SCRIPT, 615 FN_SET_SUB_SCRIPT, SID_ATTR_CHAR_CASEMAP, SID_ATTR_CHAR_LANGUAGE, 616 SID_ATTR_CHAR_KERNING, SID_CHAR_DLG, SID_ATTR_CHAR_WORDLINEMODE, 617 FN_GROW_FONT_SIZE, FN_SHRINK_FONT_SIZE, FN_TXTATR_INET, 618 FN_FORMAT_DROPCAPS, SID_ATTR_PARA_ADJUST, SID_ATTR_PARA_LINESPACE, 619 SID_ATTR_PARA_SPLIT, SID_ATTR_PARA_KEEP, SID_ATTR_PARA_WIDOWS, 620 SID_ATTR_PARA_ORPHANS, 621 SID_ATTR_PARA_MODEL, SID_PARA_DLG, 622 FN_SELECT_PARA, SID_DEC_INDENT, 623 SID_INC_INDENT 624 }; 625 static bool bFirst = true; 626 if ( bFirst ) 627 { 628 qsort( static_cast<void*>(aROIds), SAL_N_ELEMENTS(aROIds), sizeof(sal_uInt16), lcl_CmpIds ); 629 bFirst = false; 630 } 631 if ( SfxItemState::DISABLED == eStateRO ) 632 { 633 rDis.SetSlotFilter( SfxSlotFilterState::ENABLED_READONLY, aROIds ); 634 bChgd = true; 635 } 636 } 637 else if( m_pWrtShell->IsAllProtect() ) 638 { 639 if ( SfxItemState::DISABLED == eStateProtAll ) 640 { 641 static sal_uInt16 aAllProtIds[] = { SID_SAVEDOC, FN_EDIT_REGION }; 642 static bool bAllProtFirst = true; 643 if ( bAllProtFirst ) 644 { 645 qsort( static_cast<void*>(aAllProtIds), SAL_N_ELEMENTS(aAllProtIds), sizeof(sal_uInt16), lcl_CmpIds ); 646 bAllProtFirst = false; 647 } 648 rDis.SetSlotFilter( SfxSlotFilterState::ENABLED_READONLY, aAllProtIds ); 649 bChgd = true; 650 } 651 } 652 else if ( SfxItemState::DISABLED != eStateRO || 653 SfxItemState::DISABLED != eStateProtAll ) 654 { 655 bChgd = true; 656 rDis.SetSlotFilter(); 657 } 658 if ( bChgd ) 659 GetViewFrame()->GetBindings().InvalidateAll(true); 660 } 661 662 void SwView::CheckReadonlySelection() 663 { 664 SfxDisableFlags nDisableFlags = SfxDisableFlags::NONE; 665 SfxDispatcher &rDis = GetDispatcher(); 666 667 if( m_pWrtShell->HasReadonlySel() && 668 ( !m_pWrtShell->GetDrawView() || 669 !m_pWrtShell->GetDrawView()->GetMarkedObjectList().GetMarkCount() )) 670 nDisableFlags |= SfxDisableFlags::SwOnProtectedCursor; 671 672 if( (SfxDisableFlags::SwOnProtectedCursor & nDisableFlags ) != 673 (SfxDisableFlags::SwOnProtectedCursor & rDis.GetDisableFlags() ) ) 674 { 675 // Additionally move at the Window the InputContext, so that 676 // in japanese / chinese versions the external input will be 677 // turned on or off. This but only if the correct shell is on 678 // the stack. 679 switch( m_pViewImpl->GetShellMode() ) 680 { 681 case ShellMode::Text: 682 case ShellMode::ListText: 683 case ShellMode::TableText: 684 case ShellMode::TableListText: 685 { 686 // Temporary solution!!! Should set the font of the current insertion point 687 // at each cursor movement, so outside of this "if". But TH does not 688 // evaluates the font at this time and the "purchase" appears to me 689 // as too expensive. 690 // Moreover, we don't have a font, but only attributes from which the 691 // text formatting and the correct font will be build together. 692 693 InputContext aCntxt( GetEditWin().GetInputContext() ); 694 aCntxt.SetOptions( SfxDisableFlags::SwOnProtectedCursor & nDisableFlags 695 ? (aCntxt.GetOptions() & ~ 696 InputContextFlags( InputContextFlags::Text | 697 InputContextFlags::ExtText )) 698 : (aCntxt.GetOptions() | 699 ( InputContextFlags::Text | 700 InputContextFlags::ExtText )) ); 701 GetEditWin().SetInputContext( aCntxt ); 702 } 703 break; 704 default: 705 ; 706 } 707 708 } 709 710 if( nDisableFlags != rDis.GetDisableFlags() ) 711 { 712 rDis.SetDisableFlags( nDisableFlags ); 713 GetViewFrame()->GetBindings().InvalidateAll( true ); 714 } 715 } 716 717 SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) 718 : SfxViewShell( _pFrame, SWVIEWFLAGS ), 719 m_nNewPage(USHRT_MAX), 720 m_nOldPageNum(0), 721 m_pNumRuleNodeFromDoc(nullptr), 722 m_pEditWin( VclPtr<SwEditWin>::Create( &_pFrame->GetWindow(), *this ) ), 723 m_pShell(nullptr), 724 m_pFormShell(nullptr), 725 m_pHScrollbar(nullptr), 726 m_pVScrollbar(nullptr), 727 m_pScrollFill(VclPtr<ScrollBarBox>::Create( &_pFrame->GetWindow(), WB_SIZEABLE )), 728 m_pVRuler(VclPtr<SvxRuler>::Create(&GetViewFrame()->GetWindow(), m_pEditWin, 729 SvxRulerSupportFlags::TABS | SvxRulerSupportFlags::PARAGRAPH_MARGINS_VERTICAL| 730 SvxRulerSupportFlags::BORDERS | SvxRulerSupportFlags::REDUCED_METRIC, 731 GetViewFrame()->GetBindings(), 732 WB_VSCROLL | WB_EXTRAFIELD | WB_BORDER )), 733 m_pLastTableFormat(nullptr), 734 m_pFormatClipboard(new SwFormatClipboard()), 735 m_nSelectionType( SelectionType::All ), 736 m_nPageCnt(0), 737 m_nDrawSfxId( USHRT_MAX ), 738 m_nFormSfxId( USHRT_MAX ), 739 m_eFormObjKind(OBJ_NONE), 740 m_nLastPasteDestination( static_cast<SotExchangeDest>(0xFFFF) ), 741 m_nLeftBorderDistance( 0 ), 742 m_nRightBorderDistance( 0 ), 743 m_eLastSearchCommand( static_cast<SvxSearchCmd>(0xFFFF) ), 744 m_bWheelScrollInProgress(false), 745 m_bCenterCursor(false), 746 m_bTopCursor(false), 747 m_bTabColFromDoc(false), 748 m_bTabRowFromDoc(false), 749 m_bSetTabColFromDoc(false), 750 m_bSetTabRowFromDoc(false), 751 m_bAttrChgNotified(false), 752 m_bAttrChgNotifiedWithRegistrations(false), 753 m_bVerbsActive(false), 754 m_bDrawRotate(false), 755 m_bDrawSelMode(true), 756 m_bShowAtResize(true), 757 m_bInOuterResizePixel(false), 758 m_bInInnerResizePixel(false), 759 m_bPasteState(false), 760 m_bPasteSpecialState(false), 761 m_bInMailMerge(false), 762 m_bInDtor(false), 763 m_bOldShellWasPagePreview(false), 764 m_bIsPreviewDoubleClick(false), 765 m_bMakeSelectionVisible(false), 766 m_bForceChangesToolbar(true), 767 m_nLOKPageUpDownOffset(0) 768 { 769 static bool bRequestDoubleBuffering = getenv("VCL_DOUBLEBUFFERING_ENABLE"); 770 if (bRequestDoubleBuffering) 771 m_pEditWin->RequestDoubleBuffering(true); 772 773 // According to discussion with MBA and further 774 // investigations, no old SfxViewShell will be set as parameter <pOldSh>, 775 // if function "New Window" is performed to open an additional view beside 776 // an already existing one. 777 // If the view is switch from one to another, the 'old' view is given by 778 // parameter <pOldSh>. 779 780 bDocSzUpdated = true; 781 782 CreateScrollbar( true ); 783 CreateScrollbar( false ); 784 785 m_pViewImpl.reset(new SwView_Impl(this)); 786 SetName("View"); 787 SetWindow( m_pEditWin ); 788 789 m_aTimer.SetTimeout( 120 ); 790 791 SwDocShell& rDocSh = dynamic_cast<SwDocShell&>(*_pFrame->GetObjectShell()); 792 bool bOldModifyFlag = rDocSh.IsEnableSetModified(); 793 if (bOldModifyFlag) 794 rDocSh.EnableSetModified( false ); 795 // HACK: SwDocShell has some cached font info, VCL informs about font updates, 796 // but loading of docs with embedded fonts happens after SwDocShell is created 797 // but before SwEditWin (which handles the VCL event) is created. So update 798 // manually. 799 if (rDocSh.GetDoc()->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_FONTS )) 800 rDocSh.UpdateFontList(); 801 bool bWebDShell = dynamic_cast<const SwWebDocShell*>(&rDocSh) != nullptr; 802 803 const SwMasterUsrPref *pUsrPref = SW_MOD()->GetUsrPref(bWebDShell); 804 SwViewOption aUsrPref( *pUsrPref); 805 806 //! get lingu options without loading lingu DLL 807 SvtLinguOptions aLinguOpt; 808 SvtLinguConfig().GetOptions( aLinguOpt ); 809 aUsrPref.SetOnlineSpell( aLinguOpt.bIsSpellAuto ); 810 811 bool bOldShellWasSrcView = false; 812 813 // determine if there is an existing view for 814 // document 815 SfxViewShell* pExistingSh = nullptr; 816 if ( pOldSh ) 817 { 818 pExistingSh = pOldSh; 819 // determine type of existing view 820 if (SwPagePreview* pPagePreview = dynamic_cast<SwPagePreview *>(pExistingSh)) 821 { 822 m_sSwViewData = pPagePreview->GetPrevSwViewData(); 823 m_sNewCursorPos = pPagePreview->GetNewCursorPos(); 824 m_nNewPage = pPagePreview->GetNewPage(); 825 m_bOldShellWasPagePreview = true; 826 m_bIsPreviewDoubleClick = !m_sNewCursorPos.isEmpty() || m_nNewPage != USHRT_MAX; 827 } 828 else if (dynamic_cast<const SwSrcView *>(pExistingSh) != nullptr) 829 bOldShellWasSrcView = true; 830 } 831 832 SAL_INFO( "sw.ui", "before create WrtShell" ); 833 if (SwView *pView = dynamic_cast<SwView*>(pExistingSh)) 834 { 835 m_pWrtShell.reset(new SwWrtShell(*pView->m_pWrtShell, m_pEditWin, *this)); 836 } 837 else if (SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>(rDocSh.GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell())) 838 { 839 m_pWrtShell.reset(new SwWrtShell(*pWrtShell, m_pEditWin, *this)); 840 } 841 else 842 { 843 SwDoc& rDoc = *rDocSh.GetDoc(); 844 845 if( !bOldShellWasSrcView && bWebDShell && !m_bOldShellWasPagePreview ) 846 aUsrPref.setBrowseMode( true ); 847 else 848 aUsrPref.setBrowseMode( rDoc.getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) ); 849 850 //For the BrowseMode we do not assume a factor. 851 if( aUsrPref.getBrowseMode() && aUsrPref.GetZoomType() != SvxZoomType::PERCENT ) 852 { 853 aUsrPref.SetZoomType( SvxZoomType::PERCENT ); 854 aUsrPref.SetZoom( 100 ); 855 } 856 if (rDocSh.IsPreview()) 857 { 858 aUsrPref.SetZoomType( SvxZoomType::WHOLEPAGE ); 859 aUsrPref.SetViewLayoutBookMode( false ); 860 aUsrPref.SetViewLayoutColumns( 1 ); 861 } 862 m_pWrtShell.reset(new SwWrtShell(rDoc, m_pEditWin, *this, &aUsrPref)); 863 // creating an SwView from a SwPagePreview needs to 864 // add the SwViewShell to the ring of the other SwViewShell(s) 865 if(m_bOldShellWasPagePreview) 866 { 867 SwViewShell& rPreviewViewShell = *static_cast<SwPagePreview*>(pExistingSh)->GetViewShell(); 868 m_pWrtShell->MoveTo(&rPreviewViewShell); 869 // to update the field command et.al. if necessary 870 const SwViewOption* pPreviewOpt = rPreviewViewShell.GetViewOptions(); 871 if( pPreviewOpt->IsFieldName() != aUsrPref.IsFieldName() || 872 pPreviewOpt->IsShowHiddenField() != aUsrPref.IsShowHiddenField() || 873 pPreviewOpt->IsShowHiddenPara() != aUsrPref.IsShowHiddenPara() || 874 pPreviewOpt->IsShowHiddenChar() != aUsrPref.IsShowHiddenChar() ) 875 rPreviewViewShell.ApplyViewOptions(aUsrPref); 876 // reset design mode at draw view for form 877 // shell, if needed. 878 if ( static_cast<SwPagePreview*>(pExistingSh)->ResetFormDesignMode() && 879 m_pWrtShell->HasDrawView() ) 880 { 881 SdrView* pDrawView = m_pWrtShell->GetDrawView(); 882 pDrawView->SetDesignMode( static_cast<SwPagePreview*>(pExistingSh)->FormDesignModeToReset() ); 883 } 884 } 885 } 886 SAL_INFO( "sw.ui", "after create WrtShell" ); 887 m_pHRuler = VclPtr<SwCommentRuler>::Create(m_pWrtShell.get(), &GetViewFrame()->GetWindow(), m_pEditWin, 888 SvxRulerSupportFlags::TABS | 889 SvxRulerSupportFlags::PARAGRAPH_MARGINS | 890 SvxRulerSupportFlags::BORDERS | 891 SvxRulerSupportFlags::NEGATIVE_MARGINS| 892 SvxRulerSupportFlags::REDUCED_METRIC, 893 GetViewFrame()->GetBindings(), 894 WB_STDRULER | WB_EXTRAFIELD | WB_BORDER); 895 896 // assure that modified state of document 897 // isn't reset, if document is already modified. 898 const bool bIsDocModified = m_pWrtShell->GetDoc()->getIDocumentState().IsModified(); 899 900 // Thus among other things, the HRuler is not displayed in the read-only case. 901 aUsrPref.SetReadonly( m_pWrtShell->GetViewOptions()->IsReadonly() ); 902 903 // no margin for OLE! 904 Size aBrwsBorder; 905 if( SfxObjectCreateMode::EMBEDDED != rDocSh.GetCreateMode() ) 906 aBrwsBorder = GetMargin(); 907 908 m_pWrtShell->SetBrowseBorder( aBrwsBorder ); 909 910 // In CTOR no shell changes may take place, which must be temporarily stored 911 // with the timer. Otherwise, the SFX removes them from the stack! 912 bool bOld = g_bNoInterrupt; 913 g_bNoInterrupt = true; 914 915 m_pHRuler->SetActive(); 916 m_pVRuler->SetActive(); 917 918 SfxViewFrame* pViewFrame = GetViewFrame(); 919 920 StartListening(*pViewFrame, DuplicateHandling::Prevent); 921 StartListening(rDocSh, DuplicateHandling::Prevent); 922 923 // Set Zoom-factor from HRuler 924 Fraction aZoomFract( aUsrPref.GetZoom(), 100 ); 925 m_pHRuler->SetZoom( aZoomFract ); 926 m_pVRuler->SetZoom( aZoomFract ); 927 m_pHRuler->SetDoubleClickHdl(LINK( this, SwView, ExecRulerClick )); 928 FieldUnit eMetric = pUsrPref->GetHScrollMetric(); 929 m_pHRuler->SetUnit( eMetric ); 930 931 eMetric = pUsrPref->GetVScrollMetric(); 932 m_pVRuler->SetUnit( eMetric ); 933 934 m_pHRuler->SetCharWidth( 371 ); // default character width 935 m_pVRuler->SetLineHeight( 551 ); // default line height 936 937 // Set DocShell 938 m_xGlueDocShell.reset(new SwViewGlueDocShell(*this, rDocSh)); 939 m_pPostItMgr.reset(new SwPostItMgr(this)); 940 941 // Check and process the DocSize. Via the handler, the shell could not 942 // be found, because the shell is not known in the SFX management 943 // within the CTOR phase. 944 DocSzChgd( m_pWrtShell->GetDocSize() ); 945 946 // Set AttrChangedNotify link 947 m_pWrtShell->SetChgLnk(LINK(this, SwView, AttrChangedNotify)); 948 949 if (rDocSh.GetCreateMode() == SfxObjectCreateMode::EMBEDDED && 950 !rDocSh.GetVisArea(ASPECT_CONTENT).IsEmpty()) 951 SetVisArea(rDocSh.GetVisArea(ASPECT_CONTENT),false); 952 953 SAL_WARN_IF( 954 officecfg::Office::Common::Undo::Steps::get() <= 0, 955 "sw.ui", "/org.openoffice.Office.Common/Undo/Steps <= 0"); 956 if (!utl::ConfigManager::IsFuzzing() && 0 < officecfg::Office::Common::Undo::Steps::get()) 957 { 958 m_pWrtShell->DoUndo(); 959 } 960 961 const bool bBrowse = m_pWrtShell->GetViewOptions()->getBrowseMode(); 962 // Disable "multiple window" 963 SetNewWindowAllowed(!bBrowse); 964 // End of disabled multiple window 965 966 m_bVScrollbarEnabled = aUsrPref.IsViewVScrollBar(); 967 m_bHScrollbarEnabled = aUsrPref.IsViewHScrollBar(); 968 m_pHScrollbar->SetAuto(bBrowse); 969 if( aUsrPref.IsViewHRuler() ) 970 CreateTab(); 971 if( aUsrPref.IsViewVRuler() ) 972 CreateVRuler(); 973 974 m_pWrtShell->SetUIOptions( aUsrPref ); 975 m_pWrtShell->SetReadOnlyAvailable( aUsrPref.IsCursorInProtectedArea() ); 976 m_pWrtShell->ApplyAccessibilityOptions(SW_MOD()->GetAccessibilityOptions()); 977 978 if( m_pWrtShell->GetDoc()->getIDocumentState().IsUpdateExpField() ) 979 { 980 if (m_pWrtShell->GetDoc()->GetDocumentFieldsManager().containsUpdatableFields()) 981 { 982 CurrShell aCurr(m_pWrtShell.get()); 983 m_pWrtShell->StartAction(); 984 m_pWrtShell->CalcLayout(); 985 m_pWrtShell->GetDoc()->getIDocumentFieldsAccess().UpdateFields(false); 986 m_pWrtShell->EndAction(); 987 } 988 m_pWrtShell->GetDoc()->getIDocumentState().SetUpdateExpFieldStat( false ); 989 } 990 991 // Update all tables if necessary: 992 if( m_pWrtShell->GetDoc()->IsUpdateTOX() ) 993 { 994 SfxRequest aSfxRequest( FN_UPDATE_TOX, SfxCallMode::SLOT, GetPool() ); 995 Execute( aSfxRequest ); 996 m_pWrtShell->GetDoc()->SetUpdateTOX( false ); // reset again 997 m_pWrtShell->SttEndDoc(true); 998 } 999 1000 // No ResetModified, if there is already a view to this doc. 1001 SfxViewFrame* pVFrame = GetViewFrame(); 1002 SfxViewFrame* pFirst = SfxViewFrame::GetFirst(&rDocSh); 1003 // Currently(360) the view is registered firstly after the CTOR, 1004 // the following expression is also working if this changes. 1005 // If the modification cannot be canceled by undo, then do NOT set 1006 // the modify back. 1007 // no reset of modified state, if document 1008 // was already modified. 1009 if (!m_pWrtShell->GetDoc()->GetIDocumentUndoRedo().IsUndoNoResetModified() && 1010 ( !pFirst || pFirst == pVFrame ) && 1011 !bIsDocModified ) 1012 { 1013 m_pWrtShell->ResetModified(); 1014 } 1015 1016 g_bNoInterrupt = bOld; 1017 1018 // If a new GlobalDoc will be created, the navigator will also be generated. 1019 if( dynamic_cast<const SwGlobalDocShell*>(&rDocSh) != nullptr && 1020 !pVFrame->GetChildWindow( SID_NAVIGATOR )) 1021 { 1022 SfxBoolItem aNavi(SID_NAVIGATOR, true); 1023 GetDispatcher().ExecuteList(SID_NAVIGATOR, SfxCallMode::ASYNCHRON, { &aNavi }); 1024 } 1025 1026 uno::Reference< frame::XFrame > xFrame = pVFrame->GetFrame().GetFrameInterface(); 1027 1028 uno::Reference< frame::XFrame > xBeamerFrame = xFrame->findFrame( 1029 "_beamer", frame::FrameSearchFlag::CHILDREN); 1030 if(xBeamerFrame.is()) 1031 { 1032 SwDBData aData = m_pWrtShell->GetDBData(); 1033 SwModule::ShowDBObj( *this, aData ); 1034 } 1035 1036 // has anybody calls the attrchanged handler in the constructor? 1037 if( m_bAttrChgNotifiedWithRegistrations ) 1038 { 1039 GetViewFrame()->GetBindings().LEAVEREGISTRATIONS(); 1040 if( m_aTimer.IsActive() ) 1041 m_aTimer.Stop(); 1042 } 1043 1044 m_aTimer.SetInvokeHandler(LINK(this, SwView, TimeoutHdl)); 1045 m_aTimer.SetDebugName( "sw::SwView m_aTimer" ); 1046 m_bAttrChgNotified = m_bAttrChgNotifiedWithRegistrations = false; 1047 if (bOldModifyFlag) 1048 rDocSh.EnableSetModified(); 1049 InvalidateBorder(); 1050 1051 if( !m_pHScrollbar->IsVisible( true ) ) 1052 ShowHScrollbar( false ); 1053 if( !m_pVScrollbar->IsVisible( true ) ) 1054 ShowVScrollbar( false ); 1055 1056 GetViewFrame()->GetWindow().AddChildEventListener( LINK( this, SwView, WindowChildEventListener ) ); 1057 } 1058 1059 SwViewGlueDocShell::SwViewGlueDocShell(SwView& rView, SwDocShell& rDocSh) 1060 : m_rView(rView) 1061 { 1062 // Set DocShell 1063 rDocSh.SetView(&m_rView); 1064 SW_MOD()->SetView(&m_rView); 1065 } 1066 1067 SwViewGlueDocShell::~SwViewGlueDocShell() 1068 { 1069 SwDocShell* pDocSh = m_rView.GetDocShell(); 1070 if (pDocSh && pDocSh->GetView() == &m_rView) 1071 pDocSh->SetView(nullptr); 1072 if (SW_MOD()->GetView() == &m_rView) 1073 SW_MOD()->SetView(nullptr); 1074 } 1075 1076 SwView::~SwView() 1077 { 1078 // Notify other LOK views that we are going away. 1079 SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", "false"); 1080 SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", ""); 1081 SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY"); 1082 1083 // Need to remove activated field's button before disposing EditWin. 1084 GetWrtShell().getIDocumentMarkAccess()->ClearFieldActivation(); 1085 1086 GetViewFrame()->GetWindow().RemoveChildEventListener( LINK( this, SwView, WindowChildEventListener ) ); 1087 m_pPostItMgr.reset(); 1088 1089 m_bInDtor = true; 1090 m_pEditWin->Hide(); // prevent problems with painting 1091 1092 // Set pointer in SwDocShell to the view again 1093 m_xGlueDocShell.reset(); 1094 1095 if( m_aTimer.IsActive() && m_bAttrChgNotifiedWithRegistrations ) 1096 GetViewFrame()->GetBindings().LEAVEREGISTRATIONS(); 1097 1098 // the last view must end the text edit 1099 SdrView *pSdrView = m_pWrtShell ? m_pWrtShell->GetDrawView() : nullptr; 1100 if( pSdrView && pSdrView->IsTextEdit() ) 1101 pSdrView->SdrEndTextEdit( true ); 1102 1103 SetWindow( nullptr ); 1104 1105 m_pViewImpl->Invalidate(); 1106 EndListening(*GetViewFrame()); 1107 EndListening(*GetDocShell()); 1108 m_pScrollFill.disposeAndClear(); 1109 m_pWrtShell.reset(); // reset here so that it is not accessible by the following dtors. 1110 m_pHScrollbar.disposeAndClear(); 1111 m_pVScrollbar.disposeAndClear(); 1112 m_pHRuler.disposeAndClear(); 1113 m_pVRuler.disposeAndClear(); 1114 m_pGlosHdl.reset(); 1115 m_pViewImpl.reset(); 1116 1117 // If this was enabled in the ctor for the frame, then disable it here. 1118 static bool bRequestDoubleBuffering = getenv("VCL_DOUBLEBUFFERING_ENABLE"); 1119 if (bRequestDoubleBuffering) 1120 m_pEditWin->RequestDoubleBuffering(false); 1121 m_pEditWin.disposeAndClear(); 1122 1123 m_pFormatClipboard.reset(); 1124 } 1125 1126 SwDocShell* SwView::GetDocShell() 1127 { 1128 SfxObjectShell* pDocShell = GetViewFrame()->GetObjectShell(); 1129 return dynamic_cast<SwDocShell*>( pDocShell ); 1130 } 1131 1132 // Remember CursorPos 1133 1134 void SwView::WriteUserData( OUString &rUserData, bool bBrowse ) 1135 { 1136 // The browse flag will be passed from Sfx when documents are browsed 1137 // (not to be confused with the BrowseMode). 1138 // Then that stored data are not persistent! 1139 1140 const SwRect& rRect = m_pWrtShell->GetCharRect(); 1141 const tools::Rectangle& rVis = GetVisArea(); 1142 1143 rUserData = OUString::number( rRect.Left() ); 1144 rUserData += ";"; 1145 rUserData += OUString::number( rRect.Top() ); 1146 rUserData += ";"; 1147 rUserData += OUString::number( m_pWrtShell->GetViewOptions()->GetZoom() ); 1148 rUserData += ";"; 1149 rUserData += OUString::number( rVis.Left() ); 1150 rUserData += ";"; 1151 rUserData += OUString::number( rVis.Top() ); 1152 rUserData += ";"; 1153 rUserData += OUString::number( bBrowse ? SAL_MIN_INT32 : rVis.Right()); 1154 rUserData += ";"; 1155 rUserData += OUString::number( bBrowse ? SAL_MIN_INT32 : rVis.Bottom()); 1156 rUserData += ";"; 1157 rUserData += OUString::number( 1158 static_cast<sal_uInt16>(m_pWrtShell->GetViewOptions()->GetZoomType()));//eZoom; 1159 rUserData += ";"; 1160 rUserData += FrameTypeFlags::NONE == m_pWrtShell->GetSelFrameType() ? OUStringLiteral(u"0") : OUStringLiteral(u"1"); 1161 } 1162 1163 // Set CursorPos 1164 1165 static bool lcl_IsOwnDocument( SwView& rView ) 1166 { 1167 uno::Reference<document::XDocumentPropertiesSupplier> xDPS( 1168 rView.GetDocShell()->GetModel(), uno::UNO_QUERY_THROW); 1169 uno::Reference<document::XDocumentProperties> xDocProps 1170 = xDPS->getDocumentProperties(); 1171 OUString Created = xDocProps->getAuthor(); 1172 OUString Changed = xDocProps->getModifiedBy(); 1173 OUString FullName = SW_MOD()->GetUserOptions().GetFullName(); 1174 return !FullName.isEmpty() 1175 && (Changed == FullName || (Changed.isEmpty() && Created == FullName)); 1176 } 1177 1178 void SwView::ReadUserData( const OUString &rUserData, bool bBrowse ) 1179 { 1180 if ( !(rUserData.indexOf(';')>=0 && // more than one token 1181 // For document without layout only in the onlinelayout or 1182 // while forward/backward 1183 (!m_pWrtShell->IsNewLayout() || m_pWrtShell->GetViewOptions()->getBrowseMode() || bBrowse)) ) 1184 return; 1185 1186 bool bIsOwnDocument = lcl_IsOwnDocument( *this ); 1187 1188 CurrShell aCurr(m_pWrtShell.get()); 1189 1190 sal_Int32 nPos = 0; 1191 1192 // No it is *not* a good idea to call GetToken within Point constr. immediately, 1193 // because which parameter is evaluated first? 1194 tools::Long nX = rUserData.getToken( 0, ';', nPos ).toInt32(), 1195 nY = rUserData.getToken( 0, ';', nPos ).toInt32(); 1196 Point aCursorPos( nX, nY ); 1197 1198 sal_uInt16 nZoomFactor = 1199 static_cast< sal_uInt16 >( rUserData.getToken(0, ';', nPos ).toInt32() ); 1200 1201 tools::Long nLeft = rUserData.getToken(0, ';', nPos ).toInt32(), 1202 nTop = rUserData.getToken(0, ';', nPos ).toInt32(), 1203 nRight = rUserData.getToken(0, ';', nPos ).toInt32(), 1204 nBottom= rUserData.getToken(0, ';', nPos ).toInt32(); 1205 1206 const tools::Long nAdd = m_pWrtShell->GetViewOptions()->getBrowseMode() ? DOCUMENTBORDER : DOCUMENTBORDER*2; 1207 if ( nBottom > (m_pWrtShell->GetDocSize().Height()+nAdd) ) 1208 return; 1209 1210 m_pWrtShell->EnableSmooth( false ); 1211 1212 const tools::Rectangle aVis( nLeft, nTop, nRight, nBottom ); 1213 1214 sal_Int32 nOff = 0; 1215 SvxZoomType eZoom; 1216 if( !m_pWrtShell->GetViewOptions()->getBrowseMode() ) 1217 eZoom = static_cast<SvxZoomType>(static_cast<sal_uInt16>(rUserData.getToken(nOff, ';', nPos ).toInt32())); 1218 else 1219 { 1220 eZoom = SvxZoomType::PERCENT; 1221 ++nOff; 1222 } 1223 1224 bool bSelectObj = (0 != rUserData.getToken( nOff, ';', nPos ).toInt32()) 1225 && m_pWrtShell->IsObjSelectable( aCursorPos ); 1226 1227 // restore editing position 1228 m_pViewImpl->SetRestorePosition(aCursorPos, bSelectObj); 1229 // set flag value to avoid macro execution. 1230 bool bSavedFlagValue = m_pWrtShell->IsMacroExecAllowed(); 1231 m_pWrtShell->SetMacroExecAllowed( false ); 1232 // os: changed: The user data has to be read if the view is switched back from page preview 1233 // go to the last editing position when opening own files 1234 if(m_bOldShellWasPagePreview || bIsOwnDocument) 1235 { 1236 m_pWrtShell->SwCursorShell::SetCursor( aCursorPos, !bSelectObj ); 1237 if( bSelectObj ) 1238 { 1239 m_pWrtShell->SelectObj( aCursorPos ); 1240 m_pWrtShell->EnterSelFrameMode( &aCursorPos ); 1241 } 1242 } 1243 1244 // reset flag value 1245 m_pWrtShell->SetMacroExecAllowed( bSavedFlagValue ); 1246 1247 // set visible area before applying 1248 // information from print preview. Otherwise, the applied information 1249 // is lost. 1250 // os: changed: The user data has to be read if the view is switched back from page preview 1251 // go to the last editing position when opening own files 1252 if(m_bOldShellWasPagePreview || bIsOwnDocument ) 1253 { 1254 if ( bBrowse ) 1255 SetVisArea( aVis.TopLeft() ); 1256 else 1257 SetVisArea( aVis ); 1258 } 1259 1260 //apply information from print preview - if available 1261 if( !m_sNewCursorPos.isEmpty() ) 1262 { 1263 sal_Int32 nIdx{ 0 }; 1264 const tools::Long nXTmp = m_sNewCursorPos.getToken( 0, ';', nIdx ).toInt32(); 1265 const tools::Long nYTmp = m_sNewCursorPos.getToken( 0, ';', nIdx ).toInt32(); 1266 Point aCursorPos2( nXTmp, nYTmp ); 1267 bSelectObj = m_pWrtShell->IsObjSelectable( aCursorPos2 ); 1268 1269 m_pWrtShell->SwCursorShell::SetCursor( aCursorPos2 ); 1270 if( bSelectObj ) 1271 { 1272 m_pWrtShell->SelectObj( aCursorPos2 ); 1273 m_pWrtShell->EnterSelFrameMode( &aCursorPos2 ); 1274 } 1275 m_pWrtShell->MakeSelVisible(); 1276 m_sNewCursorPos.clear(); 1277 } 1278 else if(USHRT_MAX != m_nNewPage) 1279 { 1280 m_pWrtShell->GotoPage(m_nNewPage, true); 1281 m_nNewPage = USHRT_MAX; 1282 } 1283 1284 SelectShell(); 1285 1286 m_pWrtShell->StartAction(); 1287 const SwViewOption* pVOpt = m_pWrtShell->GetViewOptions(); 1288 if( pVOpt->GetZoom() != nZoomFactor || pVOpt->GetZoomType() != eZoom ) 1289 SetZoom( eZoom, nZoomFactor); 1290 1291 m_pWrtShell->LockView( true ); 1292 m_pWrtShell->EndAction(); 1293 m_pWrtShell->LockView( false ); 1294 m_pWrtShell->EnableSmooth( true ); 1295 } 1296 1297 void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue >& rSequence ) 1298 { 1299 if(GetDocShell()->IsPreview()||m_bIsPreviewDoubleClick) 1300 return; 1301 bool bIsOwnDocument = lcl_IsOwnDocument( *this ); 1302 1303 CurrShell aCurr(m_pWrtShell.get()); 1304 const SwRect& rRect = m_pWrtShell->GetCharRect(); 1305 const tools::Rectangle &rVis = GetVisArea(); 1306 const SwViewOption* pVOpt = m_pWrtShell->GetViewOptions(); 1307 1308 sal_Int64 nX = rRect.Left(), nY = rRect.Top(), nLeft = rVis.Left(), nTop = rVis.Top(); 1309 sal_Int64 nRight = nLeft; 1310 sal_Int64 nBottom = LONG_MIN; 1311 sal_Int16 nZoomType = static_cast< sal_Int16 >(pVOpt->GetZoomType()); 1312 sal_Int16 nZoomFactor = static_cast < sal_Int16 > (pVOpt->GetZoom()); 1313 bool bViewLayoutBookMode = pVOpt->IsViewLayoutBookMode(); 1314 sal_Int16 nViewLayoutColumns = pVOpt->GetViewLayoutColumns(); 1315 1316 bool bSelectedFrame = ( m_pWrtShell->GetSelFrameType() != FrameTypeFlags::NONE ), 1317 bGotVisibleLeft = false, 1318 bGotVisibleTop = false, bGotVisibleRight = false, 1319 bGotVisibleBottom = false, bGotZoomType = false, 1320 bGotZoomFactor = false, bGotIsSelectedFrame = false, 1321 bGotViewLayoutColumns = false, bGotViewLayoutBookMode = false, 1322 bBrowseMode = false, bGotBrowseMode = false; 1323 1324 for (const beans::PropertyValue& rValue : rSequence) 1325 { 1326 if ( rValue.Name == "ViewLeft" ) 1327 { 1328 rValue.Value >>= nX; 1329 nX = convertMm100ToTwip( nX ); 1330 } 1331 else if ( rValue.Name == "ViewTop" ) 1332 { 1333 rValue.Value >>= nY; 1334 nY = convertMm100ToTwip( nY ); 1335 } 1336 else if ( rValue.Name == "VisibleLeft" ) 1337 { 1338 rValue.Value >>= nLeft; 1339 nLeft = convertMm100ToTwip( nLeft ); 1340 bGotVisibleLeft = true; 1341 } 1342 else if ( rValue.Name == "VisibleTop" ) 1343 { 1344 rValue.Value >>= nTop; 1345 nTop = convertMm100ToTwip( nTop ); 1346 bGotVisibleTop = true; 1347 } 1348 else if ( rValue.Name == "VisibleRight" ) 1349 { 1350 rValue.Value >>= nRight; 1351 nRight = convertMm100ToTwip( nRight ); 1352 bGotVisibleRight = true; 1353 } 1354 else if ( rValue.Name == "VisibleBottom" ) 1355 { 1356 rValue.Value >>= nBottom; 1357 nBottom = convertMm100ToTwip( nBottom ); 1358 bGotVisibleBottom = true; 1359 } 1360 else if ( rValue.Name == "ZoomType" ) 1361 { 1362 rValue.Value >>= nZoomType; 1363 bGotZoomType = true; 1364 } 1365 else if ( rValue.Name == "ZoomFactor" ) 1366 { 1367 rValue.Value >>= nZoomFactor; 1368 bGotZoomFactor = true; 1369 } 1370 else if ( rValue.Name == "ViewLayoutColumns" ) 1371 { 1372 rValue.Value >>= nViewLayoutColumns; 1373 bGotViewLayoutColumns = true; 1374 } 1375 else if ( rValue.Name == "ViewLayoutBookMode" ) 1376 { 1377 bViewLayoutBookMode = *o3tl::doAccess<bool>(rValue.Value); 1378 bGotViewLayoutBookMode = true; 1379 } 1380 else if ( rValue.Name == "IsSelectedFrame" ) 1381 { 1382 rValue.Value >>= bSelectedFrame; 1383 bGotIsSelectedFrame = true; 1384 } 1385 else if (rValue.Name == "ShowOnlineLayout") 1386 { 1387 rValue.Value >>= bBrowseMode; 1388 bGotBrowseMode = true; 1389 } 1390 // Fallback to common SdrModel processing 1391 else 1392 GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->ReadUserDataSequenceValue(&rValue); 1393 } 1394 if (bGotBrowseMode) 1395 { 1396 // delegate further 1397 GetViewImpl()->GetUNOObject_Impl()->getViewSettings()->setPropertyValue("ShowOnlineLayout", uno::Any(bBrowseMode)); 1398 } 1399 1400 SelectShell(); 1401 1402 if (!bGotVisibleBottom) 1403 return; 1404 1405 Point aCursorPos( nX, nY ); 1406 const tools::Long nAdd = m_pWrtShell->GetViewOptions()->getBrowseMode() ? DOCUMENTBORDER : DOCUMENTBORDER*2; 1407 if (nBottom > (m_pWrtShell->GetDocSize().Height()+nAdd) ) 1408 return; 1409 1410 m_pWrtShell->EnableSmooth( false ); 1411 const tools::Rectangle aVis( nLeft, nTop, nRight, nBottom ); 1412 1413 SvxZoomType eZoom; 1414 if ( !m_pWrtShell->GetViewOptions()->getBrowseMode() ) 1415 eZoom = static_cast < SvxZoomType > ( nZoomType ); 1416 else 1417 { 1418 eZoom = SvxZoomType::PERCENT; 1419 } 1420 if (bGotIsSelectedFrame) 1421 { 1422 bool bSelectObj = bSelectedFrame && m_pWrtShell->IsObjSelectable( aCursorPos ); 1423 1424 // set flag value to avoid macro execution. 1425 bool bSavedFlagValue = m_pWrtShell->IsMacroExecAllowed(); 1426 m_pWrtShell->SetMacroExecAllowed( false ); 1427 // os: changed: The user data has to be read if the view is switched back from page preview 1428 // go to the last editing position when opening own files 1429 m_pViewImpl->SetRestorePosition(aCursorPos, bSelectObj); 1430 if(m_bOldShellWasPagePreview|| bIsOwnDocument) 1431 { 1432 m_pWrtShell->SwCursorShell::SetCursor( aCursorPos, !bSelectObj ); 1433 1434 // Update the shell to toggle Header/Footer edit if needed 1435 bool bInHeader = true; 1436 if ( m_pWrtShell->IsInHeaderFooter( &bInHeader ) ) 1437 { 1438 if ( !bInHeader ) 1439 { 1440 m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Footer, true ); 1441 m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Header, false ); 1442 } 1443 else 1444 { 1445 m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Header, true ); 1446 m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Footer, false ); 1447 } 1448 1449 // Force repaint 1450 m_pWrtShell->GetWin()->Invalidate(); 1451 } 1452 if ( m_pWrtShell->IsInHeaderFooter() != m_pWrtShell->IsHeaderFooterEdit() ) 1453 m_pWrtShell->ToggleHeaderFooterEdit(); 1454 1455 if( bSelectObj ) 1456 { 1457 m_pWrtShell->SelectObj( aCursorPos ); 1458 m_pWrtShell->EnterSelFrameMode( &aCursorPos ); 1459 } 1460 } 1461 1462 // reset flag value 1463 m_pWrtShell->SetMacroExecAllowed( bSavedFlagValue ); 1464 } 1465 1466 // Set ViewLayoutSettings 1467 const bool bSetViewLayoutSettings = bGotViewLayoutColumns && bGotViewLayoutBookMode && 1468 ( pVOpt->GetViewLayoutColumns() != nViewLayoutColumns || pVOpt->IsViewLayoutBookMode() != bViewLayoutBookMode ); 1469 1470 const bool bSetViewSettings = bGotZoomType && bGotZoomFactor && 1471 ( pVOpt->GetZoom() != nZoomFactor || pVOpt->GetZoomType() != eZoom ); 1472 1473 // In case we have a 'fixed' view layout of 2 or more columns, 1474 // we have to apply the view options *before* starting the action. 1475 // Otherwise the SetZoom function cannot work correctly, because 1476 // the view layout hasn't been calculated. 1477 const bool bZoomNeedsViewLayout = bSetViewLayoutSettings && 1478 1 < nViewLayoutColumns && 1479 bSetViewSettings && 1480 eZoom != SvxZoomType::PERCENT; 1481 1482 if ( !bZoomNeedsViewLayout ) 1483 m_pWrtShell->StartAction(); 1484 1485 if ( bSetViewLayoutSettings ) 1486 SetViewLayout( nViewLayoutColumns, bViewLayoutBookMode, true ); 1487 1488 if ( bZoomNeedsViewLayout ) 1489 m_pWrtShell->StartAction(); 1490 1491 if ( bSetViewSettings ) 1492 SetZoom( eZoom, nZoomFactor, true ); 1493 1494 // os: changed: The user data has to be read if the view is switched back from page preview 1495 // go to the last editing position when opening own files 1496 if(m_bOldShellWasPagePreview||bIsOwnDocument) 1497 { 1498 if ( bGotVisibleLeft && bGotVisibleTop ) 1499 { 1500 Point aTopLeft(aVis.TopLeft()); 1501 // make sure the document is still centered 1502 const SwTwips lBorder = IsDocumentBorder() ? DOCUMENTBORDER : 2 * DOCUMENTBORDER; 1503 SwTwips nEditWidth = GetEditWin().GetOutputSize().Width(); 1504 if(nEditWidth > (m_aDocSz.Width() + lBorder )) 1505 aTopLeft.setX( ( m_aDocSz.Width() + lBorder - nEditWidth ) / 2 ); 1506 else 1507 { 1508 //check if the values are possible 1509 tools::Long nXMax = m_pHScrollbar->GetRangeMax() - m_pHScrollbar->GetVisibleSize(); 1510 if( aTopLeft.X() > nXMax ) 1511 aTopLeft.setX( nXMax < 0 ? 0 : nXMax ); 1512 } 1513 SetVisArea( aTopLeft ); 1514 } 1515 else if (bGotVisibleLeft && bGotVisibleTop && bGotVisibleRight && bGotVisibleBottom ) 1516 SetVisArea( aVis ); 1517 } 1518 1519 m_pWrtShell->LockView( true ); 1520 m_pWrtShell->EndAction(); 1521 m_pWrtShell->LockView( false ); 1522 m_pWrtShell->EnableSmooth( true ); 1523 1524 } 1525 1526 void SwView::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >& rSequence ) 1527 { 1528 const SwRect& rRect = m_pWrtShell->GetCharRect(); 1529 const tools::Rectangle& rVis = GetVisArea(); 1530 1531 std::vector<beans::PropertyValue> aVector; 1532 1533 sal_uInt16 nViewID( GetViewFrame()->GetCurViewId()); 1534 aVector.push_back(comphelper::makePropertyValue("ViewId", "view" + OUString::number(nViewID))); 1535 1536 aVector.push_back(comphelper::makePropertyValue("ViewLeft", convertTwipToMm100 ( rRect.Left() ))); 1537 1538 aVector.push_back(comphelper::makePropertyValue("ViewTop", convertTwipToMm100 ( rRect.Top() ))); 1539 1540 auto visibleLeft = convertTwipToMm100 ( rVis.Left() ); 1541 aVector.push_back(comphelper::makePropertyValue("VisibleLeft", visibleLeft)); 1542 1543 auto visibleTop = convertTwipToMm100 ( rVis.Top() ); 1544 aVector.push_back(comphelper::makePropertyValue("VisibleTop", visibleTop)); 1545 1546 auto visibleRight = rVis.IsWidthEmpty() ? visibleLeft : convertTwipToMm100 ( rVis.Right() ); 1547 aVector.push_back(comphelper::makePropertyValue("VisibleRight", visibleRight)); 1548 1549 auto visibleBottom = rVis.IsHeightEmpty() ? visibleTop : convertTwipToMm100 ( rVis.Bottom() ); 1550 aVector.push_back(comphelper::makePropertyValue("VisibleBottom", visibleBottom)); 1551 1552 const sal_Int16 nZoomType = static_cast< sal_Int16 >(m_pWrtShell->GetViewOptions()->GetZoomType()); 1553 aVector.push_back(comphelper::makePropertyValue("ZoomType", nZoomType)); 1554 1555 const sal_Int16 nViewLayoutColumns = static_cast< sal_Int16 >(m_pWrtShell->GetViewOptions()->GetViewLayoutColumns()); 1556 aVector.push_back(comphelper::makePropertyValue("ViewLayoutColumns", nViewLayoutColumns)); 1557 1558 aVector.push_back(comphelper::makePropertyValue("ViewLayoutBookMode", m_pWrtShell->GetViewOptions()->IsViewLayoutBookMode())); 1559 1560 aVector.push_back(comphelper::makePropertyValue("ZoomFactor", static_cast < sal_Int16 > (m_pWrtShell->GetViewOptions()->GetZoom()))); 1561 1562 aVector.push_back(comphelper::makePropertyValue("IsSelectedFrame", FrameTypeFlags::NONE != m_pWrtShell->GetSelFrameType())); 1563 1564 rSequence = comphelper::containerToSequence(aVector); 1565 1566 // Common SdrModel processing 1567 GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->WriteUserDataSequence(rSequence); 1568 } 1569 1570 void SwView::ShowCursor( bool bOn ) 1571 { 1572 //don't scroll the cursor into the visible area 1573 bool bUnlockView = !m_pWrtShell->IsViewLocked(); 1574 m_pWrtShell->LockView( true ); //lock visible section 1575 1576 if( !bOn ) 1577 m_pWrtShell->HideCursor(); 1578 else if( !m_pWrtShell->IsFrameSelected() && !m_pWrtShell->IsObjSelected() ) 1579 m_pWrtShell->ShowCursor(); 1580 1581 if( bUnlockView ) 1582 m_pWrtShell->LockView( false ); 1583 } 1584 1585 ErrCode SwView::DoVerb(sal_Int32 nVerb) 1586 { 1587 if ( !GetViewFrame()->GetFrame().IsInPlace() ) 1588 { 1589 SwWrtShell &rSh = GetWrtShell(); 1590 const SelectionType nSel = rSh.GetSelectionType(); 1591 if ( nSel & SelectionType::Ole ) 1592 rSh.LaunchOLEObj( nVerb ); 1593 } 1594 return ERRCODE_NONE; 1595 } 1596 1597 // only return true for a text selection 1598 1599 bool SwView::HasSelection( bool bText ) const 1600 { 1601 return bText ? GetWrtShell().SwCursorShell::HasSelection() 1602 : GetWrtShell().HasSelection(); 1603 } 1604 1605 OUString SwView::GetSelectionText( bool bCompleteWrds ) 1606 { 1607 return GetSelectionTextParam( bCompleteWrds, true ); 1608 } 1609 1610 OUString SwView::GetSelectionTextParam( bool bCompleteWrds, bool bEraseTrail ) 1611 { 1612 OUString sReturn; 1613 if( bCompleteWrds && !GetWrtShell().HasSelection() ) 1614 GetWrtShell().SelWrd(); 1615 1616 GetWrtShell().GetSelectedText( sReturn ); 1617 if( bEraseTrail ) 1618 sReturn = comphelper::string::stripEnd(sReturn, ' '); 1619 return sReturn; 1620 } 1621 1622 SwGlossaryHdl* SwView::GetGlosHdl() 1623 { 1624 if(!m_pGlosHdl) 1625 m_pGlosHdl.reset(new SwGlossaryHdl(GetViewFrame(), m_pWrtShell.get())); 1626 return m_pGlosHdl.get(); 1627 } 1628 1629 void SwView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) 1630 { 1631 bool bCallBase = true; 1632 if(auto pChangedHint = dynamic_cast<const FmDesignModeChangedHint*>(&rHint)) 1633 { 1634 bool bDesignMode = pChangedHint->GetDesignMode(); 1635 if (!bDesignMode && GetDrawFuncPtr()) 1636 { 1637 GetDrawFuncPtr()->Deactivate(); 1638 SetDrawFuncPtr(nullptr); 1639 LeaveDrawCreate(); 1640 AttrChangedNotify(nullptr); 1641 } 1642 } 1643 else 1644 { 1645 if (auto pSfxEventHint = dynamic_cast<const SfxEventHint*>(&rHint)) 1646 { 1647 switch( pSfxEventHint->GetEventId() ) 1648 { 1649 case SfxEventHintId::CreateDoc: 1650 case SfxEventHintId::OpenDoc: 1651 { 1652 OUString sDataSourceName = GetDataSourceName(); 1653 if ( !sDataSourceName.isEmpty() && !IsDataSourceAvailable(sDataSourceName)) 1654 AppendDataSourceInfobar(); 1655 } 1656 break; 1657 default: 1658 break; 1659 } 1660 } 1661 1662 SfxHintId nId = rHint.GetId(); 1663 1664 switch ( nId ) 1665 { 1666 // sub shells will be destroyed by the 1667 // dispatcher, if the view frame is dying. Thus, reset member <pShell>. 1668 case SfxHintId::Dying: 1669 { 1670 if ( &rBC == GetViewFrame() ) 1671 { 1672 ResetSubShell(); 1673 } 1674 } 1675 break; 1676 case SfxHintId::ModeChanged: 1677 { 1678 // Modal mode change-over? 1679 bool bModal = GetDocShell()->IsInModalMode(); 1680 m_pHRuler->SetActive( !bModal ); 1681 m_pVRuler->SetActive( !bModal ); 1682 } 1683 1684 [[fallthrough]]; 1685 1686 case SfxHintId::TitleChanged: 1687 if ( GetDocShell()->IsReadOnly() != GetWrtShell().GetViewOptions()->IsReadonly() ) 1688 { 1689 SwWrtShell &rSh = GetWrtShell(); 1690 rSh.SetReadonlyOption( GetDocShell()->IsReadOnly() ); 1691 1692 if ( rSh.GetViewOptions()->IsViewVRuler() ) 1693 CreateVRuler(); 1694 else 1695 KillVRuler(); 1696 if ( rSh.GetViewOptions()->IsViewHRuler() ) 1697 CreateTab(); 1698 else 1699 KillTab(); 1700 bool bReadonly = GetDocShell()->IsReadOnly(); 1701 // if document is to be opened in alive-mode then this has to be 1702 // regarded while switching from readonly-mode to edit-mode 1703 if( !bReadonly ) 1704 { 1705 SwDrawModel * pDrawDoc = GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(); 1706 if (pDrawDoc) 1707 { 1708 if( !pDrawDoc->GetOpenInDesignMode() ) 1709 break;// don't touch the design mode 1710 } 1711 } 1712 SfxBoolItem aItem( SID_FM_DESIGN_MODE, !bReadonly); 1713 GetDispatcher().ExecuteList(SID_FM_DESIGN_MODE, 1714 SfxCallMode::ASYNCHRON, { &aItem }); 1715 } 1716 break; 1717 1718 case SfxHintId::SwDrawViewsCreated: 1719 { 1720 bCallBase = false; 1721 if ( GetFormShell() ) 1722 { 1723 GetFormShell()->SetView(dynamic_cast<FmFormView*>(GetWrtShell().GetDrawView())); 1724 SfxBoolItem aItem( SID_FM_DESIGN_MODE, !GetDocShell()->IsReadOnly()); 1725 GetDispatcher().ExecuteList(SID_FM_DESIGN_MODE, 1726 SfxCallMode::SYNCHRON, { &aItem }); 1727 } 1728 } 1729 break; 1730 case SfxHintId::RedlineChanged: 1731 { 1732 static sal_uInt16 const aSlotRedLine[] = { 1733 FN_REDLINE_ACCEPT_DIRECT, 1734 FN_REDLINE_REJECT_DIRECT, 1735 FN_REDLINE_NEXT_CHANGE, 1736 FN_REDLINE_PREV_CHANGE, 1737 FN_REDLINE_ACCEPT_ALL, 1738 FN_REDLINE_REJECT_ALL, 1739 0 1740 }; 1741 GetViewFrame()->GetBindings().Invalidate(aSlotRedLine); 1742 } 1743 break; 1744 default: break; 1745 } 1746 } 1747 1748 if ( bCallBase ) 1749 SfxViewShell::Notify(rBC, rHint); 1750 } 1751 1752 #if defined(_WIN32) || defined UNX 1753 1754 void SwView::ScannerEventHdl() 1755 { 1756 uno::Reference< XScannerManager2 > xScanMgr = SW_MOD()->GetScannerManager(); 1757 if( xScanMgr.is() ) 1758 { 1759 const ScannerContext aContext( xScanMgr->getAvailableScanners().getConstArray()[ 0 ] ); 1760 const ScanError eError = xScanMgr->getError( aContext ); 1761 1762 if( ScanError_ScanErrorNone == eError ) 1763 { 1764 const uno::Reference< awt::XBitmap > xBitmap( xScanMgr->getBitmap( aContext ) ); 1765 1766 if( xBitmap.is() ) 1767 { 1768 const BitmapEx aScanBmp( VCLUnoHelper::GetBitmap( xBitmap ) ); 1769 1770 if( !aScanBmp.IsEmpty() ) 1771 { 1772 Graphic aGrf(aScanBmp); 1773 m_pWrtShell->Insert( OUString(), OUString(), aGrf ); 1774 } 1775 } 1776 } 1777 } 1778 SfxBindings& rBind = GetViewFrame()->GetBindings(); 1779 rBind.Invalidate( SID_TWAIN_SELECT ); 1780 rBind.Invalidate( SID_TWAIN_TRANSFER ); 1781 } 1782 #endif 1783 1784 void SwView::StopShellTimer() 1785 { 1786 if(m_aTimer.IsActive()) 1787 { 1788 m_aTimer.Stop(); 1789 if ( m_bAttrChgNotifiedWithRegistrations ) 1790 { 1791 GetViewFrame()->GetBindings().LEAVEREGISTRATIONS(); 1792 m_bAttrChgNotifiedWithRegistrations = false; 1793 } 1794 SelectShell(); 1795 m_bAttrChgNotified = false; 1796 } 1797 } 1798 1799 bool SwView::PrepareClose( bool bUI ) 1800 { 1801 SfxViewFrame* pVFrame = GetViewFrame(); 1802 pVFrame->SetChildWindow( SwInputChild::GetChildWindowId(), false ); 1803 if( pVFrame->GetDispatcher()->IsLocked() ) 1804 pVFrame->GetDispatcher()->Lock(false); 1805 1806 if ( m_pFormShell && !m_pFormShell->PrepareClose( bUI ) ) 1807 { 1808 return false; 1809 } 1810 return SfxViewShell::PrepareClose( bUI ); 1811 } 1812 1813 // status methods for clipboard. 1814 // Status changes now notified from the clipboard. 1815 bool SwView::IsPasteAllowed() 1816 { 1817 SotExchangeDest nPasteDestination = SwTransferable::GetSotDestination( *m_pWrtShell ); 1818 if( m_nLastPasteDestination != nPasteDestination ) 1819 { 1820 TransferableDataHelper aDataHelper( 1821 TransferableDataHelper::CreateFromSystemClipboard( 1822 &GetEditWin()) ); 1823 if( aDataHelper.GetXTransferable().is() ) 1824 { 1825 m_bPasteState = SwTransferable::IsPaste( *m_pWrtShell, aDataHelper ); 1826 m_bPasteSpecialState = SwTransferable::IsPasteSpecial( 1827 *m_pWrtShell, aDataHelper ); 1828 } 1829 else 1830 m_bPasteState = m_bPasteSpecialState = false; 1831 1832 if( static_cast<SotExchangeDest>(0xFFFF) == m_nLastPasteDestination ) // the init value 1833 m_pViewImpl->AddClipboardListener(); 1834 m_nLastPasteDestination = nPasteDestination; 1835 } 1836 return m_bPasteState; 1837 } 1838 1839 bool SwView::IsPasteSpecialAllowed() 1840 { 1841 if ( m_pFormShell && m_pFormShell->IsActiveControl() ) 1842 return false; 1843 1844 SotExchangeDest nPasteDestination = SwTransferable::GetSotDestination( *m_pWrtShell ); 1845 if( m_nLastPasteDestination != nPasteDestination ) 1846 { 1847 TransferableDataHelper aDataHelper( 1848 TransferableDataHelper::CreateFromSystemClipboard( 1849 &GetEditWin()) ); 1850 if( aDataHelper.GetXTransferable().is() ) 1851 { 1852 m_bPasteState = SwTransferable::IsPaste( *m_pWrtShell, aDataHelper ); 1853 m_bPasteSpecialState = SwTransferable::IsPasteSpecial( 1854 *m_pWrtShell, aDataHelper ); 1855 } 1856 else 1857 m_bPasteState = m_bPasteSpecialState = false; 1858 1859 if( static_cast<SotExchangeDest>(0xFFFF) == m_nLastPasteDestination ) // the init value 1860 m_pViewImpl->AddClipboardListener(); 1861 } 1862 return m_bPasteSpecialState; 1863 } 1864 1865 bool SwView::IsPasteSpreadsheet(bool bHasOwnTableCopied) 1866 { 1867 TransferableDataHelper aDataHelper( 1868 TransferableDataHelper::CreateFromSystemClipboard( 1869 &GetEditWin()) ); 1870 if( aDataHelper.GetXTransferable().is() ) 1871 { 1872 if (bHasOwnTableCopied && SwTransferable::IsPasteOwnFormat( aDataHelper )) 1873 return true; 1874 return aDataHelper.HasFormat( SotClipboardFormatId::SYLK ) || aDataHelper.HasFormat( SotClipboardFormatId::SYLK_BIGCAPS ); 1875 } 1876 return false; 1877 } 1878 1879 void SwView::NotifyDBChanged() 1880 { 1881 GetViewImpl()->GetUNOObject_Impl()->NotifyDBChanged(); 1882 } 1883 1884 // Printing 1885 1886 SfxObjectShellLock SwView::CreateTmpSelectionDoc() 1887 { 1888 SwXTextView *const pTempImpl = GetViewImpl()->GetUNOObject_Impl(); 1889 return pTempImpl->BuildTmpSelectionDoc(); 1890 } 1891 1892 void SwView::AddTransferable(SwTransferable& rTransferable) 1893 { 1894 GetViewImpl()->AddTransferable(rTransferable); 1895 } 1896 1897 tools::Rectangle SwView::getLOKVisibleArea() const 1898 { 1899 SwViewShell* pVwSh = GetWrtShellPtr(); 1900 if (pVwSh) 1901 return pVwSh->getLOKVisibleArea(); 1902 else 1903 return tools::Rectangle(); 1904 } 1905 1906 OUString SwView::GetDataSourceName() const 1907 { 1908 uno::Reference<lang::XMultiServiceFactory> xFactory(GetDocShell()->GetModel(), uno::UNO_QUERY); 1909 uno::Reference<beans::XPropertySet> xSettings( 1910 xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY); 1911 OUString sDataSourceName = ""; 1912 xSettings->getPropertyValue("CurrentDatabaseDataSource") >>= sDataSourceName; 1913 1914 return sDataSourceName; 1915 } 1916 1917 bool SwView::IsDataSourceAvailable(const OUString sDataSourceName) 1918 { 1919 uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); 1920 Reference< XDatabaseContext> xDatabaseContext = DatabaseContext::create(xContext); 1921 1922 return xDatabaseContext->hasByName(sDataSourceName); 1923 } 1924 1925 void SwView::AppendDataSourceInfobar() 1926 { 1927 auto pInfoBar = GetViewFrame()->AppendInfoBar("datasource", "", 1928 SwResId(STR_DATASOURCE_NOT_AVAILABLE), 1929 InfobarType::WARNING); 1930 if (!pInfoBar) 1931 return; 1932 1933 weld::Button& rBtn = pInfoBar->addButton(); 1934 rBtn.set_label(SwResId(STR_EXCHANGE_DATABASE)); 1935 rBtn.connect_clicked(LINK(this, SwView, ExchangeDatabaseHandler)); 1936 } 1937 1938 namespace sw { 1939 1940 void InitPrintOptionsFromApplication(SwPrintData & o_rData, bool const bWeb) 1941 { 1942 o_rData = *SW_MOD()->GetPrtOptions(bWeb); 1943 } 1944 1945 } // namespace sw 1946 1947 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1948
