1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ 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 <sal/log.hxx> 23 #include <svl/stritem.hxx> 24 #include <svl/eitem.hxx> 25 #include <svl/whiter.hxx> 26 #include <vcl/toolbox.hxx> 27 #include <vcl/svapp.hxx> 28 #include <vcl/weld.hxx> 29 #include <svl/intitem.hxx> 30 #include <svtools/langhelp.hxx> 31 #include <com/sun/star/frame/XLayoutManager.hpp> 32 #include <com/sun/star/frame/ModuleManager.hpp> 33 #include <com/sun/star/io/IOException.hpp> 34 #include <com/sun/star/beans/XPropertySet.hpp> 35 #include <com/sun/star/embed/EmbedStates.hpp> 36 #include <com/sun/star/embed/EmbedMisc.hpp> 37 #include <com/sun/star/embed/XEmbeddedObject.hpp> 38 #include <com/sun/star/container/XContainerQuery.hpp> 39 #include <com/sun/star/frame/XStorable.hpp> 40 #include <com/sun/star/frame/XModel.hpp> 41 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> 42 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 43 #include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp> 44 #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> 45 #include <com/sun/star/view/XRenderable.hpp> 46 #include <com/sun/star/uno/Reference.hxx> 47 #include <cppuhelper/implbase.hxx> 48 49 #include <tools/diagnose_ex.h> 50 #include <tools/urlobj.hxx> 51 #include <unotools/tempfile.hxx> 52 #include <svtools/soerr.hxx> 53 #include <tools/svborder.hxx> 54 55 #include <framework/actiontriggerhelper.hxx> 56 #include <comphelper/lok.hxx> 57 #include <comphelper/namedvaluecollection.hxx> 58 #include <comphelper/processfactory.hxx> 59 #include <comphelper/sequenceashashmap.hxx> 60 #include <toolkit/helper/vclunohelper.hxx> 61 #include <vcl/settings.hxx> 62 #include <vcl/commandinfoprovider.hxx> 63 #include <LibreOfficeKit/LibreOfficeKitEnums.h> 64 65 #include <officecfg/Office/Common.hxx> 66 #include <officecfg/Setup.hxx> 67 #include <sfx2/app.hxx> 68 #include <sfx2/flatpak.hxx> 69 #include <sfx2/viewsh.hxx> 70 #include "viewimp.hxx" 71 #include <sfx2/sfxresid.hxx> 72 #include <sfx2/request.hxx> 73 #include <sfx2/printer.hxx> 74 #include <sfx2/docfile.hxx> 75 #include <sfx2/dispatch.hxx> 76 #include <sfx2/strings.hrc> 77 #include <sfx2/sfxbasecontroller.hxx> 78 #include <sfx2/mailmodelapi.hxx> 79 #include <bluthsndapi.hxx> 80 #include <sfx2/viewfrm.hxx> 81 #include <sfx2/event.hxx> 82 #include <sfx2/ipclient.hxx> 83 #include <sfx2/sfxsids.hrc> 84 #include <sfx2/objface.hxx> 85 #include <sfx2/lokhelper.hxx> 86 #include <openuriexternally.hxx> 87 #include <shellimpl.hxx> 88 89 #include <vector> 90 #include <libxml/xmlwriter.h> 91 92 using namespace ::com::sun::star; 93 using namespace ::com::sun::star::uno; 94 using namespace ::com::sun::star::frame; 95 using namespace ::com::sun::star::beans; 96 using namespace ::com::sun::star::util; 97 using namespace ::cppu; 98 99 #define ShellClass_SfxViewShell 100 #include <sfxslots.hxx> 101 102 103 class SfxClipboardChangeListener : public ::cppu::WeakImplHelper< 104 datatransfer::clipboard::XClipboardListener > 105 { 106 public: 107 SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr ); 108 109 // XEventListener 110 virtual void SAL_CALL disposing( const lang::EventObject& rEventObject ) override; 111 112 // XClipboardListener 113 virtual void SAL_CALL changedContents( const datatransfer::clipboard::ClipboardEvent& rEventObject ) override; 114 115 void DisconnectViewShell() { m_pViewShell = nullptr; } 116 void ChangedContents(); 117 118 enum AsyncExecuteCmd 119 { 120 ASYNCEXECUTE_CMD_DISPOSING, 121 ASYNCEXECUTE_CMD_CHANGEDCONTENTS 122 }; 123 124 struct AsyncExecuteInfo 125 { 126 AsyncExecuteInfo( AsyncExecuteCmd eCmd, SfxClipboardChangeListener* pListener ) : 127 m_eCmd( eCmd ), m_xListener( pListener ) {} 128 129 AsyncExecuteCmd m_eCmd; 130 rtl::Reference<SfxClipboardChangeListener> m_xListener; 131 }; 132 133 private: 134 SfxViewShell* m_pViewShell; 135 uno::Reference< datatransfer::clipboard::XClipboardNotifier > m_xClpbrdNtfr; 136 uno::Reference< lang::XComponent > m_xCtrl; 137 138 DECL_STATIC_LINK( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, void*, void ); 139 }; 140 141 SfxClipboardChangeListener::SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr ) 142 : m_pViewShell( nullptr ), m_xClpbrdNtfr( xClpbrdNtfr ), m_xCtrl(pView->GetController()) 143 { 144 if ( m_xCtrl.is() ) 145 { 146 m_xCtrl->addEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this ) ) ); 147 m_pViewShell = pView; 148 } 149 if ( m_xClpbrdNtfr.is() ) 150 { 151 m_xClpbrdNtfr->addClipboardListener( uno::Reference< datatransfer::clipboard::XClipboardListener >( 152 static_cast< datatransfer::clipboard::XClipboardListener* >( this ))); 153 } 154 } 155 156 void SfxClipboardChangeListener::ChangedContents() 157 { 158 const SolarMutexGuard aGuard; 159 if (!m_pViewShell) 160 return; 161 162 SfxBindings& rBind = m_pViewShell->GetViewFrame()->GetBindings(); 163 rBind.Invalidate(SID_PASTE); 164 rBind.Invalidate(SID_PASTE_SPECIAL); 165 rBind.Invalidate(SID_CLIPBOARD_FORMAT_ITEMS); 166 167 if (comphelper::LibreOfficeKit::isActive()) 168 { 169 // In the future we might send the payload as well. 170 SfxLokHelper::notifyAllViews(LOK_CALLBACK_CLIPBOARD_CHANGED, ""); 171 } 172 } 173 174 IMPL_STATIC_LINK( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, void*, p, void ) 175 { 176 AsyncExecuteInfo* pAsyncExecuteInfo = static_cast<AsyncExecuteInfo*>(p); 177 if ( pAsyncExecuteInfo ) 178 { 179 if ( pAsyncExecuteInfo->m_xListener.is() ) 180 { 181 if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_DISPOSING ) 182 pAsyncExecuteInfo->m_xListener->DisconnectViewShell(); 183 else if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_CHANGEDCONTENTS ) 184 pAsyncExecuteInfo->m_xListener->ChangedContents(); 185 } 186 } 187 delete pAsyncExecuteInfo; 188 } 189 190 void SAL_CALL SfxClipboardChangeListener::disposing( const lang::EventObject& /*rEventObject*/ ) 191 { 192 // Either clipboard or ViewShell is going to be destroyed -> no interest in listening anymore 193 uno::Reference< lang::XComponent > xCtrl( m_xCtrl ); 194 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xNotify( m_xClpbrdNtfr ); 195 196 uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( static_cast< datatransfer::clipboard::XClipboardListener* >( this )); 197 if ( xCtrl.is() ) 198 xCtrl->removeEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this ))); 199 if ( xNotify.is() ) 200 xNotify->removeClipboardListener( xThis ); 201 202 // Make asynchronous call to avoid locking SolarMutex which is the 203 // root for many deadlocks, especially in conjunction with the "Windows" 204 // based single thread apartment clipboard code! 205 AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_DISPOSING, this ); 206 Application::PostUserEvent( LINK( nullptr, SfxClipboardChangeListener, AsyncExecuteHdl_Impl ), pInfo ); 207 } 208 209 void SAL_CALL SfxClipboardChangeListener::changedContents( const datatransfer::clipboard::ClipboardEvent& ) 210 { 211 // Make asynchronous call to avoid locking SolarMutex which is the 212 // root for many deadlocks, especially in conjunction with the "Windows" 213 // based single thread apartment clipboard code! 214 AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_CHANGEDCONTENTS, this ); 215 Application::PostUserEvent( LINK( nullptr, SfxClipboardChangeListener, AsyncExecuteHdl_Impl ), pInfo ); 216 } 217 218 sal_uInt32 SfxViewShell_Impl::m_nLastViewShellId = 0; 219 220 SfxViewShell_Impl::SfxViewShell_Impl(SfxViewShellFlags const nFlags) 221 : aInterceptorContainer( aMutex ) 222 , m_bHasPrintOptions(nFlags & SfxViewShellFlags::HAS_PRINTOPTIONS) 223 , m_nFamily(0xFFFF) // undefined, default set by TemplateDialog 224 , m_pLibreOfficeKitViewCallback(nullptr) 225 , m_pLibreOfficeKitViewData(nullptr) 226 , m_bTiledSearching(false) 227 , m_nViewShellId(SfxViewShell_Impl::m_nLastViewShellId++) 228 , m_nDocId(-1) 229 { 230 } 231 232 SfxViewShell_Impl::~SfxViewShell_Impl() 233 { 234 } 235 236 std::vector< SfxInPlaceClient* > *SfxViewShell_Impl::GetIPClients_Impl( bool bCreate ) const 237 { 238 if (!mpIPClients && bCreate) 239 mpIPClients.reset(new std::vector< SfxInPlaceClient* >); 240 return mpIPClients.get(); 241 } 242 243 SFX_IMPL_SUPERCLASS_INTERFACE(SfxViewShell,SfxShell) 244 245 void SfxViewShell::InitInterface_Impl() 246 { 247 } 248 249 250 /** search for a filter name dependent on type and module 251 */ 252 static OUString impl_retrieveFilterNameFromTypeAndModule( 253 const css::uno::Reference< css::container::XContainerQuery >& rContainerQuery, 254 const OUString& rType, 255 const OUString& rModuleIdentifier, 256 const sal_Int32 nFlags ) 257 { 258 // Retrieve filter from type 259 css::uno::Sequence< css::beans::NamedValue > aQuery { 260 { "Type", css::uno::makeAny( rType ) }, 261 { "DocumentService", css::uno::makeAny( rModuleIdentifier ) } 262 }; 263 264 css::uno::Reference< css::container::XEnumeration > xEnumeration = 265 rContainerQuery->createSubSetEnumerationByProperties( aQuery ); 266 267 OUString aFoundFilterName; 268 while ( xEnumeration->hasMoreElements() ) 269 { 270 ::comphelper::SequenceAsHashMap aFilterPropsHM( xEnumeration->nextElement() ); 271 OUString aFilterName = aFilterPropsHM.getUnpackedValueOrDefault( 272 "Name", 273 OUString() ); 274 275 sal_Int32 nFilterFlags = aFilterPropsHM.getUnpackedValueOrDefault( 276 "Flags", 277 sal_Int32( 0 ) ); 278 279 if ( nFilterFlags & nFlags ) 280 { 281 aFoundFilterName = aFilterName; 282 break; 283 } 284 } 285 286 return aFoundFilterName; 287 } 288 289 namespace { 290 291 /** search for an internal typename, which map to the current app module 292 and map also to a "family" of file formats as e.g. PDF/MS Doc/OOo Doc. 293 */ 294 enum ETypeFamily 295 { 296 E_MS_DOC, 297 E_OOO_DOC 298 }; 299 300 } 301 302 static OUString impl_searchFormatTypeForApp(const css::uno::Reference< css::frame::XFrame >& xFrame , 303 ETypeFamily eTypeFamily) 304 { 305 try 306 { 307 css::uno::Reference< css::uno::XComponentContext > xContext (::comphelper::getProcessComponentContext()); 308 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager(css::frame::ModuleManager::create(xContext)); 309 310 OUString sModule = xModuleManager->identify(xFrame); 311 OUString sType ; 312 313 switch(eTypeFamily) 314 { 315 case E_MS_DOC: 316 { 317 if ( sModule == "com.sun.star.text.TextDocument" ) 318 sType = "writer_MS_Word_2007"; 319 else 320 if ( sModule == "com.sun.star.sheet.SpreadsheetDocument" ) 321 sType = "MS Excel 2007 XML"; 322 else 323 if ( sModule == "com.sun.star.presentation.PresentationDocument" ) 324 sType = "MS PowerPoint 2007 XML"; 325 } 326 break; 327 328 case E_OOO_DOC: 329 { 330 if ( sModule == "com.sun.star.text.TextDocument" ) 331 sType = "writer8"; 332 else 333 if ( sModule == "com.sun.star.sheet.SpreadsheetDocument" ) 334 sType = "calc8"; 335 else 336 if ( sModule == "com.sun.star.drawing.DrawingDocument" ) 337 sType = "draw8"; 338 else 339 if ( sModule == "com.sun.star.presentation.PresentationDocument" ) 340 sType = "impress8"; 341 } 342 break; 343 } 344 345 return sType; 346 } 347 catch (const css::uno::RuntimeException&) 348 { 349 throw; 350 } 351 catch (const css::uno::Exception&) 352 { 353 } 354 355 return OUString(); 356 } 357 358 void SfxViewShell::NewIPClient_Impl( SfxInPlaceClient *pIPClient ) 359 { 360 pImpl->GetIPClients_Impl()->push_back(pIPClient); 361 } 362 363 void SfxViewShell::IPClientGone_Impl( SfxInPlaceClient const *pIPClient ) 364 { 365 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(); 366 367 auto it = std::find(pClients->begin(), pClients->end(), pIPClient); 368 if (it != pClients->end()) 369 pClients->erase( it ); 370 } 371 372 373 void SfxViewShell::ExecMisc_Impl( SfxRequest &rReq ) 374 { 375 const sal_uInt16 nId = rReq.GetSlot(); 376 switch( nId ) 377 { 378 case SID_STYLE_FAMILY : 379 { 380 const SfxUInt16Item* pItem = rReq.GetArg<SfxUInt16Item>(nId); 381 if (pItem) 382 { 383 pImpl->m_nFamily = pItem->GetValue(); 384 } 385 break; 386 } 387 case SID_ACTIVATE_STYLE_APPLY: 388 { 389 uno::Reference< frame::XFrame > xFrame = 390 GetViewFrame()->GetFrame().GetFrameInterface(); 391 392 Reference< beans::XPropertySet > xPropSet( xFrame, UNO_QUERY ); 393 Reference< frame::XLayoutManager > xLayoutManager; 394 if ( xPropSet.is() ) 395 { 396 try 397 { 398 Any aValue = xPropSet->getPropertyValue("LayoutManager"); 399 aValue >>= xLayoutManager; 400 if ( xLayoutManager.is() ) 401 { 402 uno::Reference< ui::XUIElement > xElement = xLayoutManager->getElement( "private:resource/toolbar/textobjectbar" ); 403 if(!xElement.is()) 404 { 405 xElement = xLayoutManager->getElement( "private:resource/toolbar/frameobjectbar" ); 406 } 407 if(!xElement.is()) 408 { 409 xElement = xLayoutManager->getElement( "private:resource/toolbar/oleobjectbar" ); 410 } 411 if(xElement.is()) 412 { 413 uno::Reference< awt::XWindow > xWin( xElement->getRealInterface(), uno::UNO_QUERY_THROW ); 414 VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( xWin ); 415 ToolBox* pTextToolbox = dynamic_cast< ToolBox* >( pWin.get() ); 416 if( pTextToolbox ) 417 { 418 ToolBox::ImplToolItems::size_type nItemCount = pTextToolbox->GetItemCount(); 419 for( ToolBox::ImplToolItems::size_type nItem = 0; nItem < nItemCount; ++nItem ) 420 { 421 sal_uInt16 nItemId = pTextToolbox->GetItemId( nItem ); 422 const OUString& rCommand = pTextToolbox->GetItemCommand( nItemId ); 423 if (rCommand == ".uno:StyleApply") 424 { 425 vcl::Window* pItemWin = pTextToolbox->GetItemWindow( nItemId ); 426 if( pItemWin ) 427 pItemWin->GrabFocus(); 428 break; 429 } 430 } 431 } 432 } 433 } 434 } 435 catch (const Exception&) 436 { 437 } 438 } 439 rReq.Done(); 440 } 441 break; 442 443 case SID_MAIL_SENDDOCASMS: 444 case SID_MAIL_SENDDOCASOOO: 445 case SID_MAIL_SENDDOCASPDF: 446 case SID_MAIL_SENDDOC: 447 case SID_MAIL_SENDDOCASFORMAT: 448 { 449 SfxObjectShell* pDoc = GetObjectShell(); 450 if ( pDoc && pDoc->QueryHiddenInformation( 451 HiddenWarningFact::WhenSaving, GetViewFrame()->GetWindow().GetFrameWeld() ) != RET_YES ) 452 break; 453 454 455 SfxMailModel aModel; 456 OUString aDocType; 457 458 const SfxStringItem* pMailRecipient = rReq.GetArg<SfxStringItem>(SID_MAIL_RECIPIENT); 459 if ( pMailRecipient ) 460 { 461 OUString aRecipient( pMailRecipient->GetValue() ); 462 OUString aMailToStr("mailto:"); 463 464 if ( aRecipient.startsWith( aMailToStr ) ) 465 aRecipient = aRecipient.copy( aMailToStr.getLength() ); 466 aModel.AddToAddress( aRecipient ); 467 } 468 const SfxStringItem* pMailDocType = rReq.GetArg<SfxStringItem>(SID_TYPE_NAME); 469 if ( pMailDocType ) 470 aDocType = pMailDocType->GetValue(); 471 472 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() ); 473 SfxMailModel::SendMailResult eResult = SfxMailModel::SEND_MAIL_ERROR; 474 475 if ( nId == SID_MAIL_SENDDOC ) 476 eResult = aModel.SaveAndSend( xFrame, OUString() ); 477 else if ( nId == SID_MAIL_SENDDOCASPDF ) 478 eResult = aModel.SaveAndSend( xFrame, "pdf_Portable_Document_Format"); 479 else if ( nId == SID_MAIL_SENDDOCASMS ) 480 { 481 aDocType = impl_searchFormatTypeForApp(xFrame, E_MS_DOC); 482 if (!aDocType.isEmpty()) 483 eResult = aModel.SaveAndSend( xFrame, aDocType ); 484 } 485 else if ( nId == SID_MAIL_SENDDOCASOOO ) 486 { 487 aDocType = impl_searchFormatTypeForApp(xFrame, E_OOO_DOC); 488 if (!aDocType.isEmpty()) 489 eResult = aModel.SaveAndSend( xFrame, aDocType ); 490 } 491 492 if ( eResult == SfxMailModel::SEND_MAIL_ERROR ) 493 { 494 vcl::Window* pWin = SfxGetpApp()->GetTopWindow(); 495 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pWin ? pWin->GetFrameWeld() : nullptr, 496 VclMessageType::Info, VclButtonsType::Ok, 497 SfxResId(STR_ERROR_SEND_MAIL))); 498 xBox->run(); 499 rReq.Ignore(); 500 } 501 else 502 rReq.Done(); 503 } 504 break; 505 506 case SID_BLUETOOTH_SENDDOC: 507 { 508 SfxBluetoothModel aModel; 509 SfxObjectShell* pDoc = GetObjectShell(); 510 if ( pDoc && pDoc->QueryHiddenInformation( 511 HiddenWarningFact::WhenSaving, GetViewFrame()->GetWindow().GetFrameWeld() ) != RET_YES ) 512 break; 513 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() ); 514 SfxMailModel::SendMailResult eResult = aModel.SaveAndSend( xFrame ); 515 if( eResult == SfxMailModel::SEND_MAIL_ERROR ) 516 { 517 vcl::Window* pWin = SfxGetpApp()->GetTopWindow(); 518 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pWin ? pWin->GetFrameWeld() : nullptr, 519 VclMessageType::Info, VclButtonsType::Ok, 520 SfxResId(STR_ERROR_SEND_MAIL))); 521 xBox->run(); 522 rReq.Ignore(); 523 } 524 else 525 rReq.Done(); 526 } 527 break; 528 529 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 530 case SID_WEBHTML: 531 { 532 const sal_Int32 FILTERFLAG_EXPORT = 0x00000002; 533 534 css::uno::Reference< lang::XMultiServiceFactory > xSMGR(::comphelper::getProcessServiceFactory(), css::uno::UNO_SET_THROW); 535 css::uno::Reference< uno::XComponentContext > xContext(::comphelper::getProcessComponentContext(), css::uno::UNO_SET_THROW); 536 css::uno::Reference< css::frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() ); 537 css::uno::Reference< css::frame::XModel > xModel; 538 539 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager( css::frame::ModuleManager::create(xContext) ); 540 541 OUString aModule; 542 try 543 { 544 aModule = xModuleManager->identify( xFrame ); 545 } 546 catch (const css::uno::RuntimeException&) 547 { 548 throw; 549 } 550 catch (const css::uno::Exception&) 551 { 552 } 553 554 if ( xFrame.is() ) 555 { 556 css::uno::Reference< css::frame::XController > xController = xFrame->getController(); 557 if ( xController.is() ) 558 xModel = xController->getModel(); 559 } 560 561 // We need at least a valid module name and model reference 562 css::uno::Reference< css::frame::XStorable > xStorable( xModel, css::uno::UNO_QUERY ); 563 if ( xModel.is() && xStorable.is() ) 564 { 565 OUString aFilterName; 566 OUString aTypeName( "generic_HTML" ); 567 OUString aFileName; 568 569 OUString aLocation = xStorable->getLocation(); 570 INetURLObject aFileObj( aLocation ); 571 572 bool bPrivateProtocol = ( aFileObj.GetProtocol() == INetProtocol::PrivSoffice ); 573 bool bHasLocation = !aLocation.isEmpty() && !bPrivateProtocol; 574 575 css::uno::Reference< css::container::XContainerQuery > xContainerQuery( 576 xSMGR->createInstance( "com.sun.star.document.FilterFactory" ), 577 css::uno::UNO_QUERY_THROW ); 578 579 // Retrieve filter from type 580 sal_Int32 nFilterFlags = FILTERFLAG_EXPORT; 581 aFilterName = impl_retrieveFilterNameFromTypeAndModule( xContainerQuery, aTypeName, aModule, nFilterFlags ); 582 if ( aFilterName.isEmpty() ) 583 { 584 // Draw/Impress uses a different type. 2nd chance try to use alternative type name 585 aFilterName = impl_retrieveFilterNameFromTypeAndModule( 586 xContainerQuery, "graphic_HTML", aModule, nFilterFlags ); 587 } 588 589 // No filter found => error 590 // No type and no location => error 591 if ( aFilterName.isEmpty() || aTypeName.isEmpty()) 592 { 593 rReq.Done(); 594 return; 595 } 596 597 // Use provided save file name. If empty determine file name 598 if ( !bHasLocation ) 599 { 600 // Create a default file name with the correct extension 601 aFileName = "webpreview"; 602 } 603 else 604 { 605 // Determine file name from model 606 INetURLObject aFObj( xStorable->getLocation() ); 607 aFileName = aFObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::NONE ); 608 } 609 610 OSL_ASSERT( !aFilterName.isEmpty() ); 611 OSL_ASSERT( !aFileName.isEmpty() ); 612 613 // Creates a temporary directory to store our predefined file into it (for the 614 // flatpak case, create it in XDG_CACHE_HOME instead of /tmp for technical reasons, 615 // so that it can be accessed by the browser running outside the sandbox): 616 OUString * parent = nullptr; 617 if (flatpak::isFlatpak() && !flatpak::createTemporaryHtmlDirectory(&parent)) 618 { 619 SAL_WARN("sfx.view", "cannot create Flatpak html temp dir"); 620 } 621 ::utl::TempFile aTempDir( parent, true ); 622 623 INetURLObject aFilePathObj( aTempDir.GetURL() ); 624 aFilePathObj.insertName( aFileName ); 625 aFilePathObj.setExtension( "htm" ); 626 627 OUString aFileURL = aFilePathObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); 628 629 css::uno::Sequence< css::beans::PropertyValue > aArgs( 1 ); 630 aArgs[0].Name = "FilterName"; 631 aArgs[0].Value <<= aFilterName; 632 633 // Store document in the html format 634 try 635 { 636 xStorable->storeToURL( aFileURL, aArgs ); 637 } 638 catch (const io::IOException&) 639 { 640 rReq.Done(); 641 return; 642 } 643 644 sfx2::openUriExternally(aFileURL, true); 645 rReq.Done(true); 646 break; 647 } 648 else 649 { 650 rReq.Done(); 651 return; 652 } 653 } 654 } 655 } 656 657 658 void SfxViewShell::GetState_Impl( SfxItemSet &rSet ) 659 { 660 661 SfxWhichIter aIter( rSet ); 662 SfxObjectShell *pSh = GetViewFrame()->GetObjectShell(); 663 for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() ) 664 { 665 switch ( nSID ) 666 { 667 668 case SID_BLUETOOTH_SENDDOC: 669 case SID_MAIL_SENDDOC: 670 case SID_MAIL_SENDDOCASFORMAT: 671 case SID_MAIL_SENDDOCASMS: 672 case SID_MAIL_SENDDOCASOOO: 673 case SID_MAIL_SENDDOCASPDF: 674 { 675 #if HAVE_FEATURE_MACOSX_SANDBOX 676 rSet.DisableItem(nSID); 677 #endif 678 if (pSh && pSh->isExportLocked() && nSID != SID_MAIL_SENDDOC) 679 rSet.DisableItem(nSID); 680 break; 681 } 682 case SID_WEBHTML: 683 { 684 if (pSh && pSh->isExportLocked()) 685 rSet.DisableItem(nSID); 686 break; 687 } 688 // Printer functions 689 case SID_PRINTDOC: 690 case SID_PRINTDOCDIRECT: 691 case SID_SETUPPRINTER: 692 case SID_PRINTER_NAME: 693 { 694 if (Application::GetSettings().GetMiscSettings().GetDisablePrinting() 695 || (pSh && pSh->isPrintLocked())) 696 { 697 rSet.DisableItem(nSID); 698 break; 699 } 700 701 SfxPrinter *pPrinter = GetPrinter(); 702 703 if ( SID_PRINTDOCDIRECT == nSID ) 704 { 705 OUString aPrinterName; 706 if ( pPrinter != nullptr ) 707 aPrinterName = pPrinter->GetName(); 708 else 709 aPrinterName = Printer::GetDefaultPrinterName(); 710 if ( !aPrinterName.isEmpty() ) 711 { 712 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() ); 713 714 OUStringBuffer aBuffer( 60 ); 715 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(".uno:PrintDefault", 716 vcl::CommandInfoProvider::GetModuleIdentifier(xFrame)); 717 aBuffer.append(vcl::CommandInfoProvider::GetLabelForCommand(aProperties)); 718 aBuffer.append( " (" ); 719 aBuffer.append( aPrinterName ); 720 aBuffer.append(')'); 721 722 rSet.Put( SfxStringItem( SID_PRINTDOCDIRECT, aBuffer.makeStringAndClear() ) ); 723 } 724 } 725 break; 726 } 727 case SID_STYLE_FAMILY : 728 { 729 rSet.Put( SfxUInt16Item( SID_STYLE_FAMILY, pImpl->m_nFamily ) ); 730 break; 731 } 732 } 733 } 734 } 735 736 737 void SfxViewShell::SetZoomFactor( const Fraction &rZoomX, 738 const Fraction &rZoomY ) 739 { 740 DBG_ASSERT( GetWindow(), "no window" ); 741 MapMode aMap( GetWindow()->GetMapMode() ); 742 aMap.SetScaleX( rZoomX ); 743 aMap.SetScaleY( rZoomY ); 744 GetWindow()->SetMapMode( aMap ); 745 } 746 747 748 ErrCode SfxViewShell::DoVerb(long /*nVerb*/) 749 750 /* [Description] 751 752 Virtual Method used to perform a Verb on a selected Object. 753 Since this Object is only known by the derived classes, they must override 754 DoVerb. 755 */ 756 757 { 758 return ERRCODE_SO_NOVERBS; 759 } 760 761 762 void SfxViewShell::OutplaceActivated( bool bActive ) 763 { 764 if ( !bActive ) 765 GetFrame()->GetFrame().Appear(); 766 } 767 768 769 void SfxViewShell::UIActivating( SfxInPlaceClient* /*pClient*/ ) 770 { 771 uno::Reference < frame::XFrame > xOwnFrame( pFrame->GetFrame().GetFrameInterface() ); 772 uno::Reference < frame::XFramesSupplier > xParentFrame = xOwnFrame->getCreator(); 773 if ( xParentFrame.is() ) 774 xParentFrame->setActiveFrame( xOwnFrame ); 775 776 pFrame->GetBindings().HidePopups(); 777 pFrame->GetDispatcher()->Update_Impl( true ); 778 } 779 780 781 void SfxViewShell::UIDeactivated( SfxInPlaceClient* /*pClient*/ ) 782 { 783 if ( !pFrame->GetFrame().IsClosing_Impl() || SfxViewFrame::Current() != pFrame ) 784 pFrame->GetDispatcher()->Update_Impl( true ); 785 pFrame->GetBindings().HidePopups(false); 786 787 pFrame->GetBindings().InvalidateAll(true); 788 } 789 790 791 SfxInPlaceClient* SfxViewShell::FindIPClient 792 ( 793 const uno::Reference < embed::XEmbeddedObject >& xObj, 794 vcl::Window* pObjParentWin 795 ) const 796 { 797 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false); 798 if ( !pClients ) 799 return nullptr; 800 801 if( !pObjParentWin ) 802 pObjParentWin = GetWindow(); 803 for (SfxInPlaceClient* pIPClient : *pClients) 804 { 805 if ( pIPClient->GetObject() == xObj && pIPClient->GetEditWin() == pObjParentWin ) 806 return pIPClient; 807 } 808 809 return nullptr; 810 } 811 812 813 SfxInPlaceClient* SfxViewShell::GetIPClient() const 814 { 815 return GetUIActiveClient(); 816 } 817 818 819 SfxInPlaceClient* SfxViewShell::GetUIActiveIPClient_Impl() const 820 { 821 // this method is needed as long as SFX still manages the border space for ChildWindows (see SfxFrame::Resize) 822 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false); 823 if ( !pClients ) 824 return nullptr; 825 826 for (SfxInPlaceClient* pIPClient : *pClients) 827 { 828 if ( pIPClient->IsUIActive() ) 829 return pIPClient; 830 } 831 832 return nullptr; 833 } 834 835 SfxInPlaceClient* SfxViewShell::GetUIActiveClient() const 836 { 837 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false); 838 if ( !pClients ) 839 return nullptr; 840 841 const bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive(); 842 843 for (SfxInPlaceClient* pIPClient : *pClients) 844 { 845 if ( pIPClient->IsObjectUIActive() || ( bIsTiledRendering && pIPClient->IsObjectInPlaceActive() ) ) 846 return pIPClient; 847 } 848 849 return nullptr; 850 } 851 852 853 void SfxViewShell::Activate( bool bMDI ) 854 { 855 if ( bMDI ) 856 { 857 SfxObjectShell *pSh = GetViewFrame()->GetObjectShell(); 858 if ( pSh->GetModel().is() ) 859 pSh->GetModel()->setCurrentController( GetViewFrame()->GetFrame().GetController() ); 860 861 SetCurrentDocument(); 862 } 863 } 864 865 866 void SfxViewShell::Deactivate(bool /*bMDI*/) 867 { 868 } 869 870 871 void SfxViewShell::Move() 872 873 /* [Description] 874 875 This virtual Method is called when the window displayed in the 876 SfxViewShell gets a StarView-Move() notification. 877 878 This base implementation does not have to be called. . 879 880 [Note] 881 882 This Method can be used to cancel a selection, in order to catch the 883 mouse movement which is due to moving a window. 884 885 For now the notification does not work In-Place. 886 */ 887 888 { 889 } 890 891 892 void SfxViewShell::OuterResizePixel 893 ( 894 const Point& /*rToolOffset*/,// Upper left corner Tools in Frame-Window 895 const Size& /*rSize*/ // All available sizes. 896 ) 897 898 /* [Description] 899 900 Override this Method to be able to react to the size-change of 901 the View. Thus the View is defined as the Edit window and also the 902 attached Tools are defined (for example the ruler). 903 904 The Edit window must not be changed either in size or position. 905 906 The Vis-Area of SfxObjectShell, its scale and position can be changed 907 here. The main use is to change the size of the Vis-Area. 908 909 If the Border is changed due to the new calculation then this has to be set 910 by <SfxViewShell::SetBorderPixel(const SvBorder&)>. The Positioning of Tools 911 is only allowed after the calling of 'SetBorderPixel'. 912 913 [Example] 914 915 void AppViewSh::OuterViewResizePixel( const Point &rOfs, const Size &rSz ) 916 { 917 // Calculate Tool position and size externally, do not set! 918 // (due to the following Border calculation) 919 Point aHLinPos...; Size aHLinSz...; 920 ... 921 922 // Calculate and Set a Border of Tools which matches rSize. 923 SvBorder aBorder... 924 SetBorderPixel( aBorder ); // Allow Positioning from here on. 925 926 // Arrange Tools 927 pHLin->SetPosSizePixel( aHLinPos, aHLinSz ); 928 ... 929 } 930 931 [Cross-reference] 932 933 <SfxViewShell::InnerResizePixel(const Point&,const Size& rSize)> 934 */ 935 936 { 937 SetBorderPixel( SvBorder() ); 938 } 939 940 941 void SfxViewShell::InnerResizePixel 942 ( 943 const Point& /*rToolOffset*/,// Upper left corner Tools in Frame-Window 944 const Size& /*rSize*/, // All available sizes. 945 bool 946 ) 947 948 /* [Description] 949 950 Override this Method to be able to react to the size-change of 951 the Edit window. 952 953 The Edit window must not be changed either in size or position. 954 Neither the Vis-Area of SfxObjectShell nor its scale or position are 955 allowed to be changed 956 957 If the Border is changed due to the new calculation then is has to be set 958 by <SfxViewShell::SetBorderPixel(const SvBorder&)>. 959 The Positioning of Tools is only allowed after the calling of 960 'SetBorderPixel'. 961 962 963 [Note] 964 965 void AppViewSh::InnerViewResizePixel( const Point &rOfs, const Size &rSz ) 966 { 967 // Calculate Tool position and size internally, do not set! 968 // (due to the following Border calculation) 969 Point aHLinPos...; Size aHLinSz...; 970 ... 971 972 // Calculate and Set a Border of Tools which matches rSize. 973 SvBorder aBorder... 974 SetBorderPixel( aBorder ); // Allow Positioning from here on. 975 976 // Arrange Tools 977 pHLin->SetPosSizePixel( aHLinPos, aHLinSz ); 978 ... 979 } 980 981 [Cross-reference] 982 983 <SfxViewShell::OuterResizePixel(const Point&,const Size& rSize)> 984 */ 985 986 { 987 SetBorderPixel( SvBorder() ); 988 } 989 990 991 void SfxViewShell::InvalidateBorder() 992 { 993 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" ); 994 995 GetViewFrame()->InvalidateBorderImpl( this ); 996 if (pImpl->m_pController.is()) 997 { 998 pImpl->m_pController->BorderWidthsChanged_Impl(); 999 } 1000 } 1001 1002 1003 void SfxViewShell::SetBorderPixel( const SvBorder &rBorder ) 1004 { 1005 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" ); 1006 1007 GetViewFrame()->SetBorderPixelImpl( this, rBorder ); 1008 1009 // notify related controller that border size is changed 1010 if (pImpl->m_pController.is()) 1011 { 1012 pImpl->m_pController->BorderWidthsChanged_Impl(); 1013 } 1014 } 1015 1016 1017 const SvBorder& SfxViewShell::GetBorderPixel() const 1018 { 1019 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" ); 1020 1021 return GetViewFrame()->GetBorderPixelImpl(); 1022 } 1023 1024 1025 void SfxViewShell::SetWindow 1026 ( 1027 vcl::Window* pViewPort // For example Null pointer in the Destructor. 1028 ) 1029 1030 /* [Description] 1031 1032 With this method the SfxViewShell is set in the data window. This is 1033 needed for the in-place container and for restoring the proper focus. 1034 1035 Even in-place-active the conversion of the ViewPort Windows is forbidden. 1036 */ 1037 1038 { 1039 if( pWindow == pViewPort ) 1040 return; 1041 1042 // Disconnect existing IP-Clients if possible 1043 DisconnectAllClients(); 1044 1045 // Switch View-Port 1046 bool bHadFocus = pWindow && pWindow->HasChildPathFocus( true ); 1047 pWindow = pViewPort; 1048 1049 if( pWindow ) 1050 { 1051 // Disable automatic GUI mirroring (right-to-left) for document windows 1052 pWindow->EnableRTL( false ); 1053 } 1054 1055 if ( bHadFocus && pWindow ) 1056 pWindow->GrabFocus(); 1057 //TODO/CLEANUP 1058 //Do we still need this Method?! 1059 //SfxGetpApp()->GrabFocus( pWindow ); 1060 } 1061 1062 1063 SfxViewShell::SfxViewShell 1064 ( 1065 SfxViewFrame* pViewFrame, /* <SfxViewFrame>, which will be 1066 displayed in this View */ 1067 SfxViewShellFlags nFlags /* See <SfxViewShell-Flags> */ 1068 ) 1069 1070 : SfxShell(this) 1071 , pImpl( new SfxViewShell_Impl(nFlags) ) 1072 , pFrame(pViewFrame) 1073 , pWindow(nullptr) 1074 , bNoNewWindow( nFlags & SfxViewShellFlags::NO_NEWWINDOW ) 1075 , mbPrinterSettingsModified(false) 1076 , maLOKLanguageTag(LANGUAGE_NONE) 1077 , maLOKLocale(LANGUAGE_NONE) 1078 , maLOKDeviceFormFactor(LOKDeviceFormFactor::UNKNOWN) 1079 { 1080 SetMargin( pViewFrame->GetMargin_Impl() ); 1081 1082 SetPool( &pViewFrame->GetObjectShell()->GetPool() ); 1083 StartListening(*pViewFrame->GetObjectShell()); 1084 1085 // Insert into list 1086 SfxViewShellArr_Impl &rViewArr = SfxGetpApp()->GetViewShells_Impl(); 1087 rViewArr.push_back(this); 1088 1089 if (comphelper::LibreOfficeKit::isActive()) 1090 { 1091 maLOKLanguageTag = SfxLokHelper::getDefaultLanguage(); 1092 maLOKLocale = SfxLokHelper::getDefaultLanguage(); 1093 1094 maLOKDeviceFormFactor = SfxLokHelper::getDeviceFormFactor(); 1095 1096 vcl::Window* pFrameWin = pViewFrame->GetWindow().GetFrameWindow(); 1097 if (pFrameWin && !pFrameWin->GetLOKNotifier()) 1098 pFrameWin->SetLOKNotifier(this, true); 1099 } 1100 } 1101 1102 1103 SfxViewShell::~SfxViewShell() 1104 { 1105 // Remove from list 1106 const SfxViewShell *pThis = this; 1107 SfxViewShellArr_Impl &rViewArr = SfxGetpApp()->GetViewShells_Impl(); 1108 SfxViewShellArr_Impl::iterator it = std::find( rViewArr.begin(), rViewArr.end(), pThis ); 1109 rViewArr.erase( it ); 1110 1111 if ( pImpl->xClipboardListener.is() ) 1112 { 1113 pImpl->xClipboardListener->DisconnectViewShell(); 1114 pImpl->xClipboardListener = nullptr; 1115 } 1116 1117 if (pImpl->m_pController.is()) 1118 { 1119 pImpl->m_pController->ReleaseShell_Impl(); 1120 pImpl->m_pController.clear(); 1121 } 1122 1123 vcl::Window* pFrameWin = GetViewFrame()->GetWindow().GetFrameWindow(); 1124 if (pFrameWin && pFrameWin->GetLOKNotifier() == this) 1125 pFrameWin->ReleaseLOKNotifier(); 1126 } 1127 1128 bool SfxViewShell::PrepareClose 1129 ( 1130 bool bUI // TRUE: Allow Dialog and so on, FALSE: silent-mode 1131 ) 1132 { 1133 if (GetViewFrame()->GetWindow().GetLOKNotifier() == this) 1134 GetViewFrame()->GetWindow().ReleaseLOKNotifier(); 1135 1136 SfxPrinter *pPrinter = GetPrinter(); 1137 if ( pPrinter && pPrinter->IsPrinting() ) 1138 { 1139 if ( bUI ) 1140 { 1141 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetViewFrame()->GetWindow().GetFrameWeld(), 1142 VclMessageType::Info, VclButtonsType::Ok, 1143 SfxResId(STR_CANT_CLOSE))); 1144 xBox->run(); 1145 } 1146 1147 return false; 1148 } 1149 1150 if( GetViewFrame()->IsInModalMode() ) 1151 return false; 1152 1153 if( bUI && GetViewFrame()->GetDispatcher()->IsLocked() ) 1154 return false; 1155 1156 return true; 1157 } 1158 1159 1160 SfxViewShell* SfxViewShell::Current() 1161 { 1162 SfxViewFrame *pCurrent = SfxViewFrame::Current(); 1163 return pCurrent ? pCurrent->GetViewShell() : nullptr; 1164 } 1165 1166 1167 SfxViewShell* SfxViewShell::Get( const Reference< XController>& i_rController ) 1168 { 1169 if ( !i_rController.is() ) 1170 return nullptr; 1171 1172 for ( SfxViewShell* pViewShell = SfxViewShell::GetFirst( false ); 1173 pViewShell; 1174 pViewShell = SfxViewShell::GetNext( *pViewShell, false ) 1175 ) 1176 { 1177 if ( pViewShell->GetController() == i_rController ) 1178 return pViewShell; 1179 } 1180 return nullptr; 1181 } 1182 1183 1184 SdrView* SfxViewShell::GetDrawView() const 1185 1186 /* [Description] 1187 1188 This virtual Method has to be overloaded by the sub classes, to be able 1189 make the Property-Editor available. 1190 1191 The default implementation does always return zero. 1192 */ 1193 1194 { 1195 return nullptr; 1196 } 1197 1198 1199 OUString SfxViewShell::GetSelectionText 1200 ( 1201 bool /*bCompleteWords*/ /* FALSE (default) 1202 Only the actual selected text is returned. 1203 1204 TRUE 1205 The selected text is expanded so that only 1206 whole words are returned. As word separators 1207 these are used: white spaces and punctuation 1208 ".,;" and single and double quotes. 1209 */ 1210 ) 1211 1212 /* [Description] 1213 1214 Override this Method to return a text that 1215 is included in the current selection. This is for example used when 1216 sending emails. 1217 1218 When called with "CompleteWords == TRUE", it is for example sufficient 1219 with having the Cursor positioned somewhere within a URL in-order 1220 to have the entire URL returned. 1221 */ 1222 1223 { 1224 return OUString(); 1225 } 1226 1227 1228 bool SfxViewShell::HasSelection( bool ) const 1229 1230 /* [Description] 1231 1232 With this virtual Method can a for example a Dialog be queried, to 1233 check if something is selected in the current view. If the Parameter 1234 is <BOOL> TRUE then it is checked whether some text is selected. 1235 */ 1236 1237 { 1238 return false; 1239 } 1240 1241 void SfxViewShell::AddSubShell( SfxShell& rShell ) 1242 { 1243 pImpl->aArr.push_back(&rShell); 1244 SfxDispatcher *pDisp = pFrame->GetDispatcher(); 1245 if ( pDisp->IsActive(*this) ) 1246 { 1247 pDisp->Push(rShell); 1248 pDisp->Flush(); 1249 } 1250 } 1251 1252 void SfxViewShell::RemoveSubShell( SfxShell* pShell ) 1253 { 1254 SfxDispatcher *pDisp = pFrame->GetDispatcher(); 1255 if ( !pShell ) 1256 { 1257 size_t nCount = pImpl->aArr.size(); 1258 if ( pDisp->IsActive(*this) ) 1259 { 1260 for(size_t n = nCount; n > 0; --n) 1261 pDisp->Pop(*pImpl->aArr[n - 1]); 1262 pDisp->Flush(); 1263 } 1264 pImpl->aArr.clear(); 1265 } 1266 else 1267 { 1268 SfxShellArr_Impl::iterator i = std::find(pImpl->aArr.begin(), pImpl->aArr.end(), pShell); 1269 if(i != pImpl->aArr.end()) 1270 { 1271 pImpl->aArr.erase(i); 1272 if(pDisp->IsActive(*this)) 1273 { 1274 pDisp->RemoveShell_Impl(*pShell); 1275 pDisp->Flush(); 1276 } 1277 } 1278 } 1279 } 1280 1281 SfxShell* SfxViewShell::GetSubShell( sal_uInt16 nNo ) 1282 { 1283 sal_uInt16 nCount = pImpl->aArr.size(); 1284 if(nNo < nCount) 1285 return pImpl->aArr[nCount - nNo - 1]; 1286 return nullptr; 1287 } 1288 1289 void SfxViewShell::PushSubShells_Impl( bool bPush ) 1290 { 1291 SfxDispatcher *pDisp = pFrame->GetDispatcher(); 1292 if ( bPush ) 1293 { 1294 for (auto const& elem : pImpl->aArr) 1295 pDisp->Push(*elem); 1296 } 1297 else if(!pImpl->aArr.empty()) 1298 { 1299 SfxShell& rPopUntil = *pImpl->aArr[0]; 1300 if ( pDisp->GetShellLevel( rPopUntil ) != USHRT_MAX ) 1301 pDisp->Pop( rPopUntil, SfxDispatcherPopFlags::POP_UNTIL ); 1302 } 1303 1304 pDisp->Flush(); 1305 } 1306 1307 1308 void SfxViewShell::WriteUserData( OUString&, bool ) 1309 { 1310 } 1311 1312 1313 void SfxViewShell::ReadUserData(const OUString&, bool ) 1314 { 1315 } 1316 1317 void SfxViewShell::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue >& ) 1318 { 1319 } 1320 1321 void SfxViewShell::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >& ) 1322 { 1323 } 1324 1325 1326 // returns the first shell of spec. type viewing the specified doc. 1327 SfxViewShell* SfxViewShell::GetFirst 1328 ( 1329 bool bOnlyVisible, 1330 const std::function< bool ( const SfxViewShell* ) >& isViewShell 1331 ) 1332 { 1333 // search for a SfxViewShell of the specified type 1334 SfxViewShellArr_Impl &rShells = SfxGetpApp()->GetViewShells_Impl(); 1335 SfxViewFrameArr_Impl &rFrames = SfxGetpApp()->GetViewFrames_Impl(); 1336 for (SfxViewShell* pShell : rShells) 1337 { 1338 if ( pShell ) 1339 { 1340 // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame 1341 // these ViewShells shouldn't be accessible anymore 1342 // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps 1343 for (SfxViewFrame* pFrame : rFrames) 1344 { 1345 if ( pFrame == pShell->GetViewFrame() ) 1346 { 1347 // only ViewShells with a valid ViewFrame will be returned 1348 if ( ( !bOnlyVisible || pFrame->IsVisible() ) && (!isViewShell || isViewShell(pShell))) 1349 return pShell; 1350 break; 1351 } 1352 } 1353 } 1354 } 1355 1356 return nullptr; 1357 } 1358 1359 1360 // returns the next shell of spec. type viewing the specified doc. 1361 1362 SfxViewShell* SfxViewShell::GetNext 1363 ( 1364 const SfxViewShell& rPrev, 1365 bool bOnlyVisible, 1366 const std::function<bool ( const SfxViewShell* )>& isViewShell 1367 ) 1368 { 1369 SfxViewShellArr_Impl &rShells = SfxGetpApp()->GetViewShells_Impl(); 1370 SfxViewFrameArr_Impl &rFrames = SfxGetpApp()->GetViewFrames_Impl(); 1371 size_t nPos; 1372 for ( nPos = 0; nPos < rShells.size(); ++nPos ) 1373 if ( rShells[nPos] == &rPrev ) 1374 break; 1375 1376 for ( ++nPos; nPos < rShells.size(); ++nPos ) 1377 { 1378 SfxViewShell *pShell = rShells[nPos]; 1379 if ( pShell ) 1380 { 1381 // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame 1382 // these ViewShells shouldn't be accessible anymore 1383 // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps 1384 for (SfxViewFrame* pFrame : rFrames) 1385 { 1386 if ( pFrame == pShell->GetViewFrame() ) 1387 { 1388 // only ViewShells with a valid ViewFrame will be returned 1389 if ( ( !bOnlyVisible || pFrame->IsVisible() ) && (!isViewShell || isViewShell(pShell)) ) 1390 return pShell; 1391 break; 1392 } 1393 } 1394 } 1395 } 1396 1397 return nullptr; 1398 } 1399 1400 1401 void SfxViewShell::Notify( SfxBroadcaster& rBC, 1402 const SfxHint& rHint ) 1403 { 1404 const SfxEventHint* pEventHint = dynamic_cast<const SfxEventHint*>(&rHint); 1405 if ( !(pEventHint && pEventHint->GetEventId() == SfxEventHintId::LoadFinished) ) 1406 return; 1407 1408 if ( !GetController().is() ) 1409 return; 1410 1411 // avoid access to dangling ViewShells 1412 SfxViewFrameArr_Impl &rFrames = SfxGetpApp()->GetViewFrames_Impl(); 1413 for (SfxViewFrame* frame : rFrames) 1414 { 1415 if ( frame == GetViewFrame() && &rBC == GetObjectShell() ) 1416 { 1417 SfxItemSet* pSet = GetObjectShell()->GetMedium()->GetItemSet(); 1418 const SfxUnoAnyItem* pItem = SfxItemSet::GetItem<SfxUnoAnyItem>(pSet, SID_VIEW_DATA, false); 1419 if ( pItem ) 1420 { 1421 pImpl->m_pController->restoreViewData( pItem->GetValue() ); 1422 pSet->ClearItem( SID_VIEW_DATA ); 1423 } 1424 break; 1425 } 1426 } 1427 } 1428 1429 bool SfxViewShell::ExecKey_Impl(const KeyEvent& aKey) 1430 { 1431 if (!pImpl->m_xAccExec) 1432 { 1433 pImpl->m_xAccExec = ::svt::AcceleratorExecute::createAcceleratorHelper(); 1434 pImpl->m_xAccExec->init(::comphelper::getProcessComponentContext(), 1435 pFrame->GetFrame().GetFrameInterface()); 1436 } 1437 1438 return pImpl->m_xAccExec->execute(aKey.GetKeyCode()); 1439 } 1440 1441 void SfxViewShell::registerLibreOfficeKitViewCallback(LibreOfficeKitCallback pCallback, void* pData) 1442 { 1443 pImpl->m_pLibreOfficeKitViewCallback = pCallback; 1444 pImpl->m_pLibreOfficeKitViewData = pData; 1445 1446 afterCallbackRegistered(); 1447 1448 if (!pCallback) 1449 return; 1450 1451 // Ask other views to tell us about their cursors. 1452 SfxViewShell* pViewShell = SfxViewShell::GetFirst(); 1453 while (pViewShell) 1454 { 1455 if (pViewShell->GetDocId() == GetDocId()) 1456 pViewShell->NotifyCursor(this); 1457 pViewShell = SfxViewShell::GetNext(*pViewShell); 1458 } 1459 } 1460 1461 void SfxViewShell::libreOfficeKitViewCallback(int nType, const char* pPayload) const 1462 { 1463 if (!comphelper::LibreOfficeKit::isActive()) 1464 return; 1465 1466 if (comphelper::LibreOfficeKit::isTiledPainting() && nType != LOK_CALLBACK_FORM_FIELD_BUTTON) 1467 return; 1468 1469 if (pImpl->m_bTiledSearching) 1470 { 1471 switch (nType) 1472 { 1473 case LOK_CALLBACK_TEXT_SELECTION: 1474 case LOK_CALLBACK_TEXT_VIEW_SELECTION: 1475 case LOK_CALLBACK_TEXT_SELECTION_START: 1476 case LOK_CALLBACK_TEXT_SELECTION_END: 1477 case LOK_CALLBACK_GRAPHIC_SELECTION: 1478 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION: 1479 return; 1480 } 1481 } 1482 1483 if (pImpl->m_pLibreOfficeKitViewCallback) 1484 pImpl->m_pLibreOfficeKitViewCallback(nType, pPayload, pImpl->m_pLibreOfficeKitViewData); 1485 else 1486 SAL_INFO( 1487 "sfx.view", 1488 "SfxViewShell::libreOfficeKitViewCallback no callback set! Dropped payload of type " 1489 << lokCallbackTypeToString(nType) << ": [" << pPayload << ']'); 1490 } 1491 1492 void SfxViewShell::afterCallbackRegistered() 1493 { 1494 } 1495 1496 vcl::Window* SfxViewShell::GetEditWindowForActiveOLEObj() const 1497 { 1498 vcl::Window* pEditWin = nullptr; 1499 SfxInPlaceClient* pIPClient = GetIPClient(); 1500 if (pIPClient) 1501 { 1502 pEditWin = pIPClient->GetEditWin(); 1503 } 1504 return pEditWin; 1505 } 1506 1507 void SfxViewShell::SetLOKLanguageTag(const OUString& rBcp47LanguageTag) 1508 { 1509 LanguageTag aTag(rBcp47LanguageTag, true); 1510 1511 css::uno::Sequence<OUString> inst(officecfg::Setup::Office::InstalledLocales::get()->getElementNames()); 1512 LanguageTag aFallbackTag = LanguageTag(getInstalledLocaleForSystemUILanguage(inst, /* bRequestInstallIfMissing */ false, rBcp47LanguageTag), true).makeFallback(); 1513 1514 // If we want de-CH, and the de localisation is available, we don't want to use de-DE as then 1515 // the magic in Translate::get() won't turn ess-zet into double s. Possibly other similar cases? 1516 if (comphelper::LibreOfficeKit::isActive() && aTag.getLanguage() == aFallbackTag.getLanguage()) 1517 maLOKLanguageTag = aTag; 1518 else 1519 maLOKLanguageTag = aFallbackTag; 1520 } 1521 1522 void SfxViewShell::SetLOKLocale(const OUString& rBcp47LanguageTag) 1523 { 1524 maLOKLocale = LanguageTag(rBcp47LanguageTag, true).makeFallback(); 1525 } 1526 1527 void SfxViewShell::NotifyCursor(SfxViewShell* /*pViewShell*/) const 1528 { 1529 } 1530 1531 void SfxViewShell::setTiledSearching(bool bTiledSearching) 1532 { 1533 pImpl->m_bTiledSearching = bTiledSearching; 1534 } 1535 1536 int SfxViewShell::getPart() const 1537 { 1538 return 0; 1539 } 1540 1541 ViewShellId SfxViewShell::GetViewShellId() const 1542 { 1543 return pImpl->m_nViewShellId; 1544 } 1545 1546 void SfxViewShell::SetDocId(ViewShellDocId nId) 1547 { 1548 assert(static_cast<int>(pImpl->m_nDocId) == -1); 1549 pImpl->m_nDocId = nId; 1550 } 1551 1552 ViewShellDocId SfxViewShell::GetDocId() const 1553 { 1554 return pImpl->m_nDocId; 1555 } 1556 1557 void SfxViewShell::NotifyOtherViews(int nType, const OString& rKey, const OString& rPayload) 1558 { 1559 SfxLokHelper::notifyOtherViews(this, nType, rKey, rPayload); 1560 } 1561 1562 void SfxViewShell::NotifyOtherView(OutlinerViewShell* pOther, int nType, const OString& rKey, const OString& rPayload) 1563 { 1564 auto pOtherShell = dynamic_cast<SfxViewShell*>(pOther); 1565 if (!pOtherShell) 1566 return; 1567 1568 SfxLokHelper::notifyOtherView(this, pOtherShell, nType, rKey, rPayload); 1569 } 1570 1571 void SfxViewShell::dumpAsXml(xmlTextWriterPtr pWriter) const 1572 { 1573 xmlTextWriterStartElement(pWriter, BAD_CAST("SfxViewShell")); 1574 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this); 1575 xmlTextWriterWriteAttribute(pWriter, BAD_CAST("id"), BAD_CAST(OString::number(static_cast<sal_Int32>(GetViewShellId())).getStr())); 1576 xmlTextWriterEndElement(pWriter); 1577 } 1578 1579 bool SfxViewShell::KeyInput( const KeyEvent &rKeyEvent ) 1580 1581 /* [Description] 1582 1583 This Method executes the KeyEvent 'rKeyEvent' of the Keys (Accelerator) 1584 configured either direct or indirect (for example by the Application) 1585 in the SfxViewShell. 1586 1587 [Return value] 1588 1589 bool TRUE 1590 The Key (Accelerator) is configured and the 1591 associated Handler was called 1592 1593 FALSE 1594 The Key (Accelerator) is not configured and 1595 subsequently no Handler was called 1596 1597 [Cross-reference] 1598 1599 <SfxApplication::KeyInput(const KeyEvent&)> 1600 */ 1601 { 1602 return ExecKey_Impl(rKeyEvent); 1603 } 1604 1605 bool SfxViewShell::GlobalKeyInput_Impl( const KeyEvent &rKeyEvent ) 1606 { 1607 return ExecKey_Impl(rKeyEvent); 1608 } 1609 1610 1611 void SfxViewShell::ShowCursor( bool /*bOn*/ ) 1612 1613 /* [Description] 1614 1615 Subclasses must override this Method so that SFx can switch the 1616 Cursor on and off, for example while a <SfxProgress> is running. 1617 */ 1618 1619 { 1620 } 1621 1622 1623 void SfxViewShell::ResetAllClients_Impl( SfxInPlaceClient const *pIP ) 1624 { 1625 1626 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false); 1627 if ( !pClients ) 1628 return; 1629 1630 for (SfxInPlaceClient* pIPClient : *pClients) 1631 { 1632 if( pIPClient != pIP ) 1633 pIPClient->ResetObject(); 1634 } 1635 } 1636 1637 1638 void SfxViewShell::DisconnectAllClients() 1639 { 1640 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false); 1641 if ( !pClients ) 1642 return; 1643 1644 for ( size_t n = 0; n < pClients->size(); ) 1645 // clients will remove themselves from the list 1646 delete pClients->at( n ); 1647 } 1648 1649 1650 void SfxViewShell::QueryObjAreaPixel( tools::Rectangle& ) const 1651 { 1652 } 1653 1654 1655 void SfxViewShell::VisAreaChanged() 1656 { 1657 std::vector< SfxInPlaceClient* > *pClients = pImpl->GetIPClients_Impl(false); 1658 if ( !pClients ) 1659 return; 1660 1661 for (SfxInPlaceClient* pIPClient : *pClients) 1662 { 1663 if ( pIPClient->IsObjectInPlaceActive() ) 1664 // client is active, notify client that the VisArea might have changed 1665 pIPClient->VisAreaChanged(); 1666 } 1667 } 1668 1669 1670 void SfxViewShell::CheckIPClient_Impl( 1671 SfxInPlaceClient const *const pIPClient, const tools::Rectangle& rVisArea) 1672 { 1673 if ( GetObjectShell()->IsInClose() ) 1674 return; 1675 1676 bool bAlwaysActive = 1677 ( ( pIPClient->GetObjectMiscStatus() & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY ) != 0 ); 1678 bool bActiveWhenVisible = 1679 ( pIPClient->GetObjectMiscStatus() & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE ) != 0; 1680 1681 // this method is called when a client is created 1682 if (pIPClient->IsObjectInPlaceActive()) 1683 return; 1684 1685 // object in client is currently not active 1686 // check if the object wants to be activated always or when it becomes at least partially visible 1687 // TODO/LATER: maybe we should use the scaled area instead of the ObjArea?! 1688 if (bAlwaysActive || (bActiveWhenVisible && rVisArea.IsOver(pIPClient->GetObjArea()))) 1689 { 1690 try 1691 { 1692 pIPClient->GetObject()->changeState( embed::EmbedStates::INPLACE_ACTIVE ); 1693 } 1694 catch (const uno::Exception&) 1695 { 1696 TOOLS_WARN_EXCEPTION("sfx.view", "SfxViewShell::CheckIPClient_Impl"); 1697 } 1698 } 1699 } 1700 1701 1702 SfxObjectShell* SfxViewShell::GetObjectShell() 1703 { 1704 return pFrame ? pFrame->GetObjectShell() : nullptr; 1705 } 1706 1707 1708 Reference< XModel > SfxViewShell::GetCurrentDocument() const 1709 { 1710 Reference< XModel > xDocument; 1711 1712 const SfxObjectShell* pDocShell( const_cast< SfxViewShell* >( this )->GetObjectShell() ); 1713 OSL_ENSURE( pDocShell, "SfxViewFrame::GetCurrentDocument: no DocShell!?" ); 1714 if ( pDocShell ) 1715 xDocument = pDocShell->GetModel(); 1716 return xDocument; 1717 } 1718 1719 1720 void SfxViewShell::SetCurrentDocument() const 1721 { 1722 uno::Reference< frame::XModel > xDocument( GetCurrentDocument() ); 1723 if ( xDocument.is() ) 1724 SfxObjectShell::SetCurrentComponent( xDocument ); 1725 } 1726 1727 1728 const Size& SfxViewShell::GetMargin() const 1729 { 1730 return pImpl->aMargin; 1731 } 1732 1733 1734 void SfxViewShell::SetMargin( const Size& rSize ) 1735 { 1736 // the default margin was verified using www.apple.com !! 1737 Size aMargin = rSize; 1738 if ( aMargin.Width() == -1 ) 1739 aMargin.setWidth( DEFAULT_MARGIN_WIDTH ); 1740 if ( aMargin.Height() == -1 ) 1741 aMargin.setHeight( DEFAULT_MARGIN_HEIGHT ); 1742 1743 if ( aMargin != pImpl->aMargin ) 1744 { 1745 pImpl->aMargin = aMargin; 1746 MarginChanged(); 1747 } 1748 } 1749 1750 void SfxViewShell::MarginChanged() 1751 { 1752 } 1753 1754 void SfxViewShell::JumpToMark( const OUString& rMark ) 1755 { 1756 SfxStringItem aMarkItem( SID_JUMPTOMARK, rMark ); 1757 GetViewFrame()->GetDispatcher()->ExecuteList( 1758 SID_JUMPTOMARK, 1759 SfxCallMode::SYNCHRON|SfxCallMode::RECORD, 1760 { &aMarkItem }); 1761 } 1762 1763 void SfxViewShell::SetController( SfxBaseController* pController ) 1764 { 1765 pImpl->m_pController = pController; 1766 1767 // there should be no old listener, but if there is one, it should be disconnected 1768 if ( pImpl->xClipboardListener.is() ) 1769 pImpl->xClipboardListener->DisconnectViewShell(); 1770 1771 pImpl->xClipboardListener = new SfxClipboardChangeListener( this, GetClipboardNotifier() ); 1772 } 1773 1774 Reference < XController > SfxViewShell::GetController() const 1775 { 1776 return pImpl->m_pController.get(); 1777 } 1778 1779 SfxBaseController* SfxViewShell::GetBaseController_Impl() const 1780 { 1781 return pImpl->m_pController.get(); 1782 } 1783 1784 void SfxViewShell::AddContextMenuInterceptor_Impl( const uno::Reference< ui::XContextMenuInterceptor >& xInterceptor ) 1785 { 1786 pImpl->aInterceptorContainer.addInterface( xInterceptor ); 1787 } 1788 1789 void SfxViewShell::RemoveContextMenuInterceptor_Impl( const uno::Reference< ui::XContextMenuInterceptor >& xInterceptor ) 1790 { 1791 pImpl->aInterceptorContainer.removeInterface( xInterceptor ); 1792 } 1793 1794 static void Change( Menu* pMenu, SfxViewShell* pView ) 1795 { 1796 SfxDispatcher *pDisp = pView->GetViewFrame()->GetDispatcher(); 1797 sal_uInt16 nCount = pMenu->GetItemCount(); 1798 for ( sal_uInt16 nPos=0; nPos<nCount; ++nPos ) 1799 { 1800 sal_uInt16 nId = pMenu->GetItemId(nPos); 1801 OUString aCmd = pMenu->GetItemCommand(nId); 1802 PopupMenu* pPopup = pMenu->GetPopupMenu(nId); 1803 if ( pPopup ) 1804 { 1805 Change( pPopup, pView ); 1806 } 1807 else if ( nId < 5000 ) 1808 { 1809 if ( aCmd.startsWith(".uno:") ) 1810 { 1811 for (sal_uInt16 nIdx=0;;) 1812 { 1813 SfxShell *pShell=pDisp->GetShell(nIdx++); 1814 if (pShell == nullptr) 1815 break; 1816 const SfxInterface *pIFace = pShell->GetInterface(); 1817 const SfxSlot* pSlot = pIFace->GetSlot( aCmd ); 1818 if ( pSlot ) 1819 { 1820 pMenu->InsertItem( pSlot->GetSlotId(), pMenu->GetItemText( nId ), 1821 pMenu->GetItemBits( nId ), OString(), nPos ); 1822 pMenu->SetItemCommand( pSlot->GetSlotId(), aCmd ); 1823 pMenu->RemoveItem( nPos+1 ); 1824 break; 1825 } 1826 } 1827 } 1828 } 1829 } 1830 } 1831 1832 1833 bool SfxViewShell::TryContextMenuInterception( Menu& rIn, const OUString& rMenuIdentifier, VclPtr<Menu>& rpOut, ui::ContextMenuExecuteEvent aEvent ) 1834 { 1835 rpOut = nullptr; 1836 bool bModified = false; 1837 1838 // create container from menu 1839 aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu( 1840 &rIn, &rMenuIdentifier ); 1841 1842 // get selection from controller 1843 aEvent.Selection.set( GetController(), uno::UNO_QUERY ); 1844 1845 // call interceptors 1846 ::comphelper::OInterfaceIteratorHelper2 aIt( pImpl->aInterceptorContainer ); 1847 while( aIt.hasMoreElements() ) 1848 { 1849 try 1850 { 1851 ui::ContextMenuInterceptorAction eAction; 1852 { 1853 SolarMutexReleaser rel; 1854 eAction = static_cast<ui::XContextMenuInterceptor*>(aIt.next())->notifyContextMenuExecute( aEvent ); 1855 } 1856 switch ( eAction ) 1857 { 1858 case ui::ContextMenuInterceptorAction_CANCELLED : 1859 // interceptor does not want execution 1860 return false; 1861 case ui::ContextMenuInterceptorAction_EXECUTE_MODIFIED : 1862 // interceptor wants his modified menu to be executed 1863 bModified = true; 1864 break; 1865 case ui::ContextMenuInterceptorAction_CONTINUE_MODIFIED : 1866 // interceptor has modified menu, but allows for calling other interceptors 1867 bModified = true; 1868 continue; 1869 case ui::ContextMenuInterceptorAction_IGNORED : 1870 // interceptor is indifferent 1871 continue; 1872 default: 1873 OSL_FAIL("Wrong return value of ContextMenuInterceptor!"); 1874 continue; 1875 } 1876 } 1877 catch (...) 1878 { 1879 aIt.remove(); 1880 } 1881 1882 break; 1883 } 1884 1885 if ( bModified ) 1886 { 1887 // container was modified, create a new window out of it 1888 rpOut = VclPtr<PopupMenu>::Create(); 1889 ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer( rpOut, aEvent.ActionTriggerContainer ); 1890 1891 Change( rpOut, this ); 1892 } 1893 1894 return true; 1895 } 1896 1897 bool SfxViewShell::TryContextMenuInterception( Menu& rMenu, const OUString& rMenuIdentifier, css::ui::ContextMenuExecuteEvent aEvent ) 1898 { 1899 bool bModified = false; 1900 1901 // create container from menu 1902 aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu( &rMenu, &rMenuIdentifier ); 1903 1904 // get selection from controller 1905 aEvent.Selection = css::uno::Reference< css::view::XSelectionSupplier >( GetController(), css::uno::UNO_QUERY ); 1906 1907 // call interceptors 1908 ::comphelper::OInterfaceIteratorHelper2 aIt( pImpl->aInterceptorContainer ); 1909 while( aIt.hasMoreElements() ) 1910 { 1911 try 1912 { 1913 css::ui::ContextMenuInterceptorAction eAction; 1914 { 1915 SolarMutexReleaser rel; 1916 eAction = static_cast< css::ui::XContextMenuInterceptor* >( aIt.next() )->notifyContextMenuExecute( aEvent ); 1917 } 1918 switch ( eAction ) 1919 { 1920 case css::ui::ContextMenuInterceptorAction_CANCELLED: 1921 // interceptor does not want execution 1922 return false; 1923 case css::ui::ContextMenuInterceptorAction_EXECUTE_MODIFIED: 1924 // interceptor wants his modified menu to be executed 1925 bModified = true; 1926 break; 1927 case css::ui::ContextMenuInterceptorAction_CONTINUE_MODIFIED: 1928 // interceptor has modified menu, but allows for calling other interceptors 1929 bModified = true; 1930 continue; 1931 case css::ui::ContextMenuInterceptorAction_IGNORED: 1932 // interceptor is indifferent 1933 continue; 1934 default: 1935 SAL_WARN( "sfx.view", "Wrong return value of ContextMenuInterceptor!" ); 1936 continue; 1937 } 1938 } 1939 catch (...) 1940 { 1941 aIt.remove(); 1942 } 1943 1944 break; 1945 } 1946 1947 if ( bModified ) 1948 { 1949 rMenu.Clear(); 1950 ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer( &rMenu, aEvent.ActionTriggerContainer ); 1951 } 1952 1953 return true; 1954 } 1955 1956 bool SfxViewShell::HandleNotifyEvent_Impl( NotifyEvent const & rEvent ) 1957 { 1958 if (pImpl->m_pController.is()) 1959 return pImpl->m_pController->HandleEvent_Impl( rEvent ); 1960 return false; 1961 } 1962 1963 bool SfxViewShell::HasKeyListeners_Impl() const 1964 { 1965 return (pImpl->m_pController.is()) 1966 && pImpl->m_pController->HasKeyListeners_Impl(); 1967 } 1968 1969 bool SfxViewShell::HasMouseClickListeners_Impl() const 1970 { 1971 return (pImpl->m_pController.is()) 1972 && pImpl->m_pController->HasMouseClickListeners_Impl(); 1973 } 1974 1975 bool SfxViewShell::Escape() 1976 { 1977 return GetViewFrame()->GetBindings().Execute( SID_TERMINATE_INPLACEACTIVATION ); 1978 } 1979 1980 Reference< view::XRenderable > SfxViewShell::GetRenderable() 1981 { 1982 Reference< view::XRenderable >xRender; 1983 SfxObjectShell* pObj = GetObjectShell(); 1984 if( pObj ) 1985 { 1986 Reference< frame::XModel > xModel( pObj->GetModel() ); 1987 if( xModel.is() ) 1988 xRender.set( xModel, UNO_QUERY ); 1989 } 1990 return xRender; 1991 } 1992 1993 void SfxViewShell::notifyWindow(vcl::LOKWindowId nDialogId, const OUString& rAction, const std::vector<vcl::LOKPayloadItem>& rPayload) const 1994 { 1995 SfxLokHelper::notifyWindow(this, nDialogId, rAction, rPayload); 1996 } 1997 1998 uno::Reference< datatransfer::clipboard::XClipboardNotifier > SfxViewShell::GetClipboardNotifier() const 1999 { 2000 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClipboardNotifier; 2001 if ( GetViewFrame() ) 2002 xClipboardNotifier.set( GetViewFrame()->GetWindow().GetClipboard(), uno::UNO_QUERY ); 2003 2004 return xClipboardNotifier; 2005 } 2006 2007 void SfxViewShell::AddRemoveClipboardListener( const uno::Reference < datatransfer::clipboard::XClipboardListener >& rClp, bool bAdd ) 2008 { 2009 try 2010 { 2011 if ( GetViewFrame() ) 2012 { 2013 uno::Reference< datatransfer::clipboard::XClipboard > xClipboard( GetViewFrame()->GetWindow().GetClipboard() ); 2014 if( xClipboard.is() ) 2015 { 2016 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClpbrdNtfr( xClipboard, uno::UNO_QUERY ); 2017 if( xClpbrdNtfr.is() ) 2018 { 2019 if( bAdd ) 2020 xClpbrdNtfr->addClipboardListener( rClp ); 2021 else 2022 xClpbrdNtfr->removeClipboardListener( rClp ); 2023 } 2024 } 2025 } 2026 } 2027 catch (const uno::Exception&) 2028 { 2029 } 2030 } 2031 2032 weld::Window* SfxViewShell::GetFrameWeld() const 2033 { 2034 return pWindow ? pWindow->GetFrameWeld() : nullptr; 2035 } 2036 2037 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 2038
