bump product version to 5.0.4.1
[LibreOffice.git] / sfx2 / source / view / viewsh.cxx
blob939c590ffa82153445ec472f0ec0dcb8c06d9aa9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include <svl/stritem.hxx>
23 #include <svl/eitem.hxx>
24 #include <svl/whiter.hxx>
25 #include <vcl/layout.hxx>
26 #include <vcl/msgbox.hxx>
27 #include <vcl/toolbox.hxx>
28 #include <svl/intitem.hxx>
29 #include <svtools/sfxecode.hxx>
30 #include <svtools/ehdl.hxx>
31 #include <com/sun/star/frame/XLayoutManager.hpp>
32 #include <com/sun/star/frame/ModuleManager.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/embed/EmbedStates.hpp>
35 #include <com/sun/star/embed/EmbedMisc.hpp>
36 #include <com/sun/star/container/XContainerQuery.hpp>
37 #include <com/sun/star/frame/XStorable.hpp>
38 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
39 #include <com/sun/star/frame/theUICommandDescription.hpp>
40 #include <cppuhelper/implbase1.hxx>
42 #include <osl/file.hxx>
43 #include <osl/mutex.hxx>
44 #include <tools/urlobj.hxx>
45 #include <unotools/tempfile.hxx>
46 #include <unotools/pathoptions.hxx>
47 #include <svtools/miscopt.hxx>
48 #include <svtools/soerr.hxx>
49 #include <svtools/embedhlp.hxx>
51 #include <basic/basmgr.hxx>
52 #include <basic/sbuno.hxx>
53 #include <framework/actiontriggerhelper.hxx>
54 #include <comphelper/processfactory.hxx>
55 #include <comphelper/sequenceashashmap.hxx>
56 #include <toolkit/helper/vclunohelper.hxx>
57 #include <vcl/settings.hxx>
59 #include <sfx2/app.hxx>
60 #include "view.hrc"
61 #include <sfx2/viewsh.hxx>
62 #include "viewimp.hxx"
63 #include <sfx2/sfxresid.hxx>
64 #include <sfx2/request.hxx>
65 #include <sfx2/templdlg.hxx>
66 #include <sfx2/printer.hxx>
67 #include <sfx2/docfile.hxx>
68 #include <sfx2/dispatch.hxx>
69 #include "arrdecl.hxx"
70 #include <sfx2/docfac.hxx>
71 #include "sfxlocal.hrc"
72 #include <sfx2/sfxbasecontroller.hxx>
73 #include <sfx2/mailmodelapi.hxx>
74 #include "bluthsndapi.hxx"
75 #include <sfx2/viewfrm.hxx>
76 #include <sfx2/event.hxx>
77 #include <sfx2/fcontnr.hxx>
78 #include <sfx2/ipclient.hxx>
79 #include "workwin.hxx"
80 #include <sfx2/objface.hxx>
81 #include <sfx2/docfilt.hxx>
82 #include "openuriexternally.hxx"
83 #include <shellimpl.hxx>
85 #include <vector>
87 using namespace ::com::sun::star;
88 using namespace ::com::sun::star::uno;
89 using namespace ::com::sun::star::frame;
90 using namespace ::com::sun::star::beans;
91 using namespace ::com::sun::star::util;
92 using namespace ::cppu;
94 #define SfxViewShell
95 #include "sfxslots.hxx"
99 class SfxClipboardChangeListener : public ::cppu::WeakImplHelper1<
100 datatransfer::clipboard::XClipboardListener >
102 public:
103 SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr );
104 virtual ~SfxClipboardChangeListener();
106 // XEventListener
107 virtual void SAL_CALL disposing( const lang::EventObject& rEventObject )
108 throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
110 // XClipboardListener
111 virtual void SAL_CALL changedContents( const datatransfer::clipboard::ClipboardEvent& rEventObject )
112 throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
114 void DisconnectViewShell() { m_pViewShell = NULL; }
115 void ChangedContents();
117 enum AsyncExecuteCmd
119 ASYNCEXECUTE_CMD_DISPOSING,
120 ASYNCEXECUTE_CMD_CHANGEDCONTENTS
123 struct AsyncExecuteInfo
125 AsyncExecuteInfo( AsyncExecuteCmd eCmd, uno::Reference< datatransfer::clipboard::XClipboardListener > xThis, SfxClipboardChangeListener* pListener ) :
126 m_eCmd( eCmd ), m_xThis( xThis ), m_pListener( pListener ) {}
128 AsyncExecuteCmd m_eCmd;
129 uno::Reference< datatransfer::clipboard::XClipboardListener > m_xThis;
130 SfxClipboardChangeListener* m_pListener;
133 private:
134 SfxViewShell* m_pViewShell;
135 uno::Reference< datatransfer::clipboard::XClipboardNotifier > m_xClpbrdNtfr;
136 uno::Reference< lang::XComponent > m_xCtrl;
138 DECL_STATIC_LINK( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, AsyncExecuteInfo* );
141 SfxClipboardChangeListener::SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr )
142 : m_pViewShell( 0 ), m_xClpbrdNtfr( xClpbrdNtfr )
144 m_xCtrl = uno::Reference < lang::XComponent >( pView->GetController(), uno::UNO_QUERY );
145 if ( m_xCtrl.is() )
147 m_xCtrl->addEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this ) ) );
148 m_pViewShell = pView;
150 if ( m_xClpbrdNtfr.is() )
152 m_xClpbrdNtfr->addClipboardListener( uno::Reference< datatransfer::clipboard::XClipboardListener >(
153 static_cast< datatransfer::clipboard::XClipboardListener* >( this )));
157 SfxClipboardChangeListener::~SfxClipboardChangeListener()
161 void SfxClipboardChangeListener::ChangedContents()
163 const SolarMutexGuard aGuard;
164 if( m_pViewShell )
166 SfxBindings& rBind = m_pViewShell->GetViewFrame()->GetBindings();
167 rBind.Invalidate( SID_PASTE );
168 rBind.Invalidate( SID_PASTE_SPECIAL );
169 rBind.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
173 IMPL_STATIC_LINK( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, AsyncExecuteInfo*, pAsyncExecuteInfo )
175 if ( pAsyncExecuteInfo )
177 uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( pAsyncExecuteInfo->m_xThis );
178 if ( pAsyncExecuteInfo->m_pListener )
180 if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_DISPOSING )
181 pAsyncExecuteInfo->m_pListener->DisconnectViewShell();
182 else if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_CHANGEDCONTENTS )
183 pAsyncExecuteInfo->m_pListener->ChangedContents();
186 delete pAsyncExecuteInfo;
188 return 0;
191 void SAL_CALL SfxClipboardChangeListener::disposing( const lang::EventObject& /*rEventObject*/ )
192 throw ( uno::RuntimeException, std::exception )
194 // Either clipboard or ViewShell is going to be destroyed -> no interest in listening anymore
195 uno::Reference< lang::XComponent > xCtrl( m_xCtrl );
196 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xNotify( m_xClpbrdNtfr );
198 uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( static_cast< datatransfer::clipboard::XClipboardListener* >( this ));
199 if ( xCtrl.is() )
200 xCtrl->removeEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this )));
201 if ( xNotify.is() )
202 xNotify->removeClipboardListener( xThis );
204 // Make asynchronous call to avoid locking SolarMutex which is the
205 // root for many deadlocks, especially in conjunction with the "Windows"
206 // based single thread apartment clipboard code!
207 AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_DISPOSING, xThis, this );
208 Application::PostUserEvent( LINK( 0, SfxClipboardChangeListener, AsyncExecuteHdl_Impl ), pInfo );
211 void SAL_CALL SfxClipboardChangeListener::changedContents( const datatransfer::clipboard::ClipboardEvent& )
212 throw ( RuntimeException, std::exception )
214 // Make asynchronous call to avoid locking SolarMutex which is the
215 // root for many deadlocks, especially in conjunction with the "Windows"
216 // based single thread apartment clipboard code!
217 uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( static_cast< datatransfer::clipboard::XClipboardListener* >( this ));
218 AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_CHANGEDCONTENTS, xThis, this );
219 Application::PostUserEvent( LINK( 0, SfxClipboardChangeListener, AsyncExecuteHdl_Impl ), pInfo );
224 static OUString RetrieveLabelFromCommand(
225 const OUString& rCommandURL,
226 const css::uno::Reference< css::frame::XFrame >& rFrame )
228 static css::uno::WeakReference< frame::XModuleManager2 > s_xModuleManager;
229 static css::uno::WeakReference< container::XNameAccess > s_xNameAccess;
231 OUString aLabel;
232 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager( s_xModuleManager );
233 css::uno::Reference< css::container::XNameAccess > xNameAccess( s_xNameAccess );
234 css::uno::Reference< css::uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
238 if ( !xModuleManager.is() )
240 xModuleManager = css::frame::ModuleManager::create(xContext);
241 s_xModuleManager = xModuleManager;
244 OUString aModuleIdentifier = xModuleManager->identify( rFrame );
246 if ( !xNameAccess.is() )
248 xNameAccess = css::uno::Reference< css::container::XNameAccess >(
249 css::frame::theUICommandDescription::get(xContext),
250 css::uno::UNO_QUERY_THROW );
251 s_xNameAccess = xNameAccess;
254 css::uno::Any a = xNameAccess->getByName( aModuleIdentifier );
255 css::uno::Reference< css::container::XNameAccess > xUICommands;
256 a >>= xUICommands;
258 OUString aStr;
259 css::uno::Sequence< css::beans::PropertyValue > aPropSeq;
261 a = xUICommands->getByName( rCommandURL );
262 if ( a >>= aPropSeq )
264 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
266 if ( aPropSeq[i].Name == "Label" )
268 aPropSeq[i].Value >>= aStr;
269 break;
272 aLabel = aStr;
275 catch (const css::uno::Exception&)
279 return aLabel;
282 class SfxInPlaceClientList
284 typedef std::vector<SfxInPlaceClient*> DataType;
285 DataType maData;
287 public:
288 typedef DataType::iterator iterator;
290 SfxInPlaceClient* at( size_t i ) { return maData.at(i); }
292 iterator begin() { return maData.begin(); }
293 iterator end() { return maData.end(); }
295 void push_back( SfxInPlaceClient* p ) { maData.push_back(p); }
296 void erase( iterator it ) { maData.erase(it); }
297 size_t size() const { return maData.size(); }
300 SfxViewShell_Impl::SfxViewShell_Impl(SfxViewShellFlags const nFlags)
301 : aInterceptorContainer( aMutex )
302 , m_bControllerSet(false)
303 , m_nPrinterLocks(0)
304 , m_bCanPrint(nFlags & SfxViewShellFlags::CAN_PRINT)
305 , m_bHasPrintOptions(nFlags & SfxViewShellFlags::HAS_PRINTOPTIONS)
306 , m_bPlugInsActive(true)
307 , m_bIsShowView(!(nFlags & SfxViewShellFlags::NO_SHOW))
308 , m_bGotOwnership(false)
309 , m_bGotFrameOwnership(false)
310 , m_nFamily(0xFFFF) // undefined, default set by TemplateDialog
311 , m_pController(0)
312 , mpIPClientList(NULL)
315 SfxViewShell_Impl::~SfxViewShell_Impl()
317 DELETEZ(mpIPClientList);
320 SfxInPlaceClientList* SfxViewShell_Impl::GetIPClientList_Impl( bool bCreate ) const
322 if (!mpIPClientList && bCreate)
323 mpIPClientList = new SfxInPlaceClientList;
324 return mpIPClientList;
327 SFX_IMPL_SUPERCLASS_INTERFACE(SfxViewShell,SfxShell)
329 void SfxViewShell::InitInterface_Impl()
333 TYPEINIT2(SfxViewShell,SfxShell,SfxListener);
335 /** search for a filter name dependent on type and module
337 static OUString impl_retrieveFilterNameFromTypeAndModule(
338 const css::uno::Reference< css::container::XContainerQuery >& rContainerQuery,
339 const OUString& rType,
340 const OUString& rModuleIdentifier,
341 const sal_Int32 nFlags )
343 // Retrieve filter from type
344 css::uno::Sequence< css::beans::NamedValue > aQuery( 2 );
345 aQuery[0].Name = "Type";
346 aQuery[0].Value = css::uno::makeAny( rType );
347 aQuery[1].Name = "DocumentService";
348 aQuery[1].Value = css::uno::makeAny( rModuleIdentifier );
350 css::uno::Reference< css::container::XEnumeration > xEnumeration =
351 rContainerQuery->createSubSetEnumerationByProperties( aQuery );
353 OUString aFoundFilterName;
354 while ( xEnumeration->hasMoreElements() )
356 ::comphelper::SequenceAsHashMap aFilterPropsHM( xEnumeration->nextElement() );
357 OUString aFilterName = aFilterPropsHM.getUnpackedValueOrDefault(
358 OUString("Name"),
359 OUString() );
361 sal_Int32 nFilterFlags = aFilterPropsHM.getUnpackedValueOrDefault(
362 OUString("Flags"),
363 sal_Int32( 0 ) );
365 if ( nFilterFlags & nFlags )
367 aFoundFilterName = aFilterName;
368 break;
372 return aFoundFilterName;
376 /** search for an internal typename, which map to the current app module
377 and map also to a "family" of file formats as e.g. PDF/MS Doc/OOo Doc.
379 enum ETypeFamily
381 E_MS_DOC,
382 E_OOO_DOC
385 OUString impl_searchFormatTypeForApp(const css::uno::Reference< css::frame::XFrame >& xFrame ,
386 ETypeFamily eTypeFamily)
390 css::uno::Reference< css::uno::XComponentContext > xContext (::comphelper::getProcessComponentContext());
391 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager(css::frame::ModuleManager::create(xContext));
393 OUString sModule = xModuleManager->identify(xFrame);
394 OUString sType ;
396 switch(eTypeFamily)
398 case E_MS_DOC:
400 if ( sModule == "com.sun.star.text.TextDocument" )
401 sType = "writer_MS_Word_97";
402 else
403 if ( sModule == "com.sun.star.sheet.SpreadsheetDocument" )
404 sType = "calc_MS_Excel_97";
405 else
406 if ( sModule == "com.sun.star.drawing.DrawingDocument" )
407 sType = "impress_MS_PowerPoint_97";
408 else
409 if ( sModule == "com.sun.star.presentation.PresentationDocument" )
410 sType = "impress_MS_PowerPoint_97";
412 break;
414 case E_OOO_DOC:
416 if ( sModule == "com.sun.star.text.TextDocument" )
417 sType = "writer8";
418 else
419 if ( sModule == "com.sun.star.sheet.SpreadsheetDocument" )
420 sType = "calc8";
421 else
422 if ( sModule == "com.sun.star.drawing.DrawingDocument" )
423 sType = "draw8";
424 else
425 if ( sModule == "com.sun.star.presentation.PresentationDocument" )
426 sType = "impress8";
428 break;
431 return sType;
433 catch (const css::uno::RuntimeException&)
435 throw;
437 catch (const css::uno::Exception&)
441 return OUString();
444 void SfxViewShell::NewIPClient_Impl( SfxInPlaceClient *pIPClient )
446 pImp->GetIPClientList_Impl(true)->push_back(pIPClient);
449 void SfxViewShell::IPClientGone_Impl( SfxInPlaceClient *pIPClient )
451 SfxInPlaceClientList* pClientList = pImp->GetIPClientList_Impl(true);
453 for( SfxInPlaceClientList::iterator it = pClientList->begin(); it != pClientList->end(); ++it )
455 if ( *it == pIPClient )
457 pClientList->erase( it );
458 break;
467 void SfxViewShell::ExecMisc_Impl( SfxRequest &rReq )
469 const sal_uInt16 nId = rReq.GetSlot();
470 switch( nId )
472 case SID_STYLE_FAMILY :
474 SFX_REQUEST_ARG(rReq, pItem, SfxUInt16Item, nId, false);
475 if (pItem)
477 pImp->m_nFamily = pItem->GetValue();
479 break;
481 case SID_ACTIVATE_STYLE_APPLY:
483 uno::Reference< frame::XFrame > xFrame(
484 GetViewFrame()->GetFrame().GetFrameInterface(),
485 uno::UNO_QUERY);
487 Reference< beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
488 Reference< frame::XLayoutManager > xLayoutManager;
489 if ( xPropSet.is() )
493 Any aValue = xPropSet->getPropertyValue("LayoutManager");
494 aValue >>= xLayoutManager;
495 if ( xLayoutManager.is() )
497 OUString aTextResString( "private:resource/toolbar/textobjectbar" );
498 uno::Reference< ui::XUIElement > xElement = xLayoutManager->getElement( aTextResString );
499 if(!xElement.is())
501 OUString aFrameResString( "private:resource/toolbar/frameobjectbar" );
502 xElement = xLayoutManager->getElement( aFrameResString );
504 if(!xElement.is())
506 OUString aOleResString( "private:resource/toolbar/oleobjectbar" );
507 xElement = xLayoutManager->getElement( aOleResString );
509 if(xElement.is())
511 uno::Reference< awt::XWindow > xWin( xElement->getRealInterface(), uno::UNO_QUERY_THROW );
512 vcl::Window* pWin = VCLUnoHelper::GetWindow( xWin );
513 ToolBox* pTextToolbox = dynamic_cast< ToolBox* >( pWin );
514 if( pTextToolbox )
516 sal_uInt16 nItemCount = pTextToolbox->GetItemCount();
517 for( sal_uInt16 nItem = 0; nItem < nItemCount; ++nItem )
519 sal_uInt16 nItemId = pTextToolbox->GetItemId( nItem );
520 const OUString& rCommand = pTextToolbox->GetItemCommand( nItemId );
521 if (rCommand == ".uno:StyleApply")
523 vcl::Window* pItemWin = pTextToolbox->GetItemWindow( nItemId );
524 if( pItemWin )
525 pItemWin->GrabFocus();
526 break;
533 catch (const Exception&)
537 rReq.Done();
539 break;
540 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
542 case SID_MAIL_SENDDOCASMS:
543 case SID_MAIL_SENDDOCASOOO:
544 case SID_MAIL_SENDDOCASPDF:
545 case SID_MAIL_SENDDOC:
546 case SID_MAIL_SENDDOCASFORMAT:
548 SfxObjectShell* pDoc = GetObjectShell();
549 if ( pDoc && pDoc->QueryHiddenInformation(
550 HiddenWarningFact::WhenSaving, &GetViewFrame()->GetWindow() ) != RET_YES )
551 break;
554 SfxMailModel aModel;
555 OUString aDocType;
557 SFX_REQUEST_ARG(rReq, pMailSubject, SfxStringItem, SID_MAIL_SUBJECT, false );
558 if ( pMailSubject )
559 aModel.SetSubject( pMailSubject->GetValue() );
561 SFX_REQUEST_ARG(rReq, pMailRecipient, SfxStringItem, SID_MAIL_RECIPIENT, false );
562 if ( pMailRecipient )
564 OUString aRecipient( pMailRecipient->GetValue() );
565 OUString aMailToStr("mailto:");
567 if ( aRecipient.startsWith( aMailToStr ) )
568 aRecipient = aRecipient.copy( aMailToStr.getLength() );
569 aModel.AddAddress( aRecipient, SfxMailModel::ROLE_TO );
571 SFX_REQUEST_ARG(rReq, pMailDocType, SfxStringItem, SID_TYPE_NAME, false );
572 if ( pMailDocType )
573 aDocType = pMailDocType->GetValue();
575 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
576 SfxMailModel::SendMailResult eResult = SfxMailModel::SEND_MAIL_ERROR;
578 if ( nId == SID_MAIL_SENDDOC )
579 eResult = aModel.SaveAndSend( xFrame, OUString() );
580 else if ( nId == SID_MAIL_SENDDOCASPDF )
581 eResult = aModel.SaveAndSend( xFrame, OUString( "pdf_Portable_Document_Format" ));
582 else if ( nId == SID_MAIL_SENDDOCASMS )
584 aDocType = impl_searchFormatTypeForApp(xFrame, E_MS_DOC);
585 if (!aDocType.isEmpty())
586 eResult = aModel.SaveAndSend( xFrame, aDocType );
588 else if ( nId == SID_MAIL_SENDDOCASOOO )
590 aDocType = impl_searchFormatTypeForApp(xFrame, E_OOO_DOC);
591 if (!aDocType.isEmpty())
592 eResult = aModel.SaveAndSend( xFrame, aDocType );
595 if ( eResult == SfxMailModel::SEND_MAIL_ERROR )
597 ScopedVclPtrInstance< MessageDialog > aBox(SfxGetpApp()->GetTopWindow(), SfxResId( STR_ERROR_SEND_MAIL ), VCL_MESSAGE_INFO);
598 aBox->Execute();
599 rReq.Ignore();
601 else
602 rReq.Done();
604 break;
606 case SID_BLUETOOTH_SENDDOC:
608 SfxBluetoothModel aModel;
609 SfxObjectShell* pDoc = GetObjectShell();
610 if ( pDoc && pDoc->QueryHiddenInformation(
611 HiddenWarningFact::WhenSaving, &GetViewFrame()->GetWindow() ) != RET_YES )
612 break;
613 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
614 SfxMailModel::SendMailResult eResult = aModel.SaveAndSend( xFrame, OUString() );
615 if( eResult == SfxMailModel::SEND_MAIL_ERROR )
617 ScopedVclPtrInstance< MessageDialog > aBox(SfxGetpApp()->GetTopWindow(), SfxResId( STR_ERROR_SEND_MAIL ), VCL_MESSAGE_INFO);
618 aBox->Execute();
619 rReq.Ignore();
621 else
622 rReq.Done();
624 break;
626 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
627 case SID_WEBHTML:
629 static const char HTML_DOCUMENT_TYPE[] = "generic_HTML";
630 static const char HTML_GRAPHIC_TYPE[] = "graphic_HTML";
631 const sal_Int32 FILTERFLAG_EXPORT = 0x00000002;
633 css::uno::Reference< lang::XMultiServiceFactory > xSMGR(::comphelper::getProcessServiceFactory(), css::uno::UNO_QUERY_THROW);
634 css::uno::Reference< uno::XComponentContext > xContext(::comphelper::getProcessComponentContext(), css::uno::UNO_QUERY_THROW);
635 css::uno::Reference< css::frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
636 css::uno::Reference< css::frame::XModel > xModel;
638 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager( css::frame::ModuleManager::create(xContext) );
640 OUString aModule;
643 aModule = xModuleManager->identify( xFrame );
645 catch (const css::uno::RuntimeException&)
647 throw;
649 catch (const css::uno::Exception&)
653 if ( xFrame.is() )
655 css::uno::Reference< css::frame::XController > xController = xFrame->getController();
656 if ( xController.is() )
657 xModel = xController->getModel();
660 // We need at least a valid module name and model reference
661 css::uno::Reference< css::frame::XStorable > xStorable( xModel, css::uno::UNO_QUERY );
662 if ( xModel.is() && xStorable.is() )
664 OUString aFilterName;
665 OUString aTypeName( HTML_DOCUMENT_TYPE );
666 OUString aFileName;
667 OUString aExtension( "htm" );
669 OUString aLocation = xStorable->getLocation();
670 INetURLObject aFileObj( aLocation );
672 bool bPrivateProtocol = ( aFileObj.GetProtocol() == INetProtocol::PrivSoffice );
673 bool bHasLocation = !aLocation.isEmpty() && !bPrivateProtocol;
675 css::uno::Reference< css::container::XContainerQuery > xContainerQuery(
676 xSMGR->createInstance( OUString(
677 "com.sun.star.document.FilterFactory" )),
678 css::uno::UNO_QUERY_THROW );
680 // Retrieve filter from type
681 sal_Int32 nFilterFlags = FILTERFLAG_EXPORT;
682 aFilterName = impl_retrieveFilterNameFromTypeAndModule( xContainerQuery, aTypeName, aModule, nFilterFlags );
683 if ( aFilterName.isEmpty() )
685 // Draw/Impress uses a different type. 2nd chance try to use alternative type name
686 aFilterName = impl_retrieveFilterNameFromTypeAndModule(
687 xContainerQuery, OUString( HTML_GRAPHIC_TYPE ), aModule, nFilterFlags );
690 // No filter found => error
691 // No type and no location => error
692 if ( aFilterName.isEmpty() || aTypeName.isEmpty())
694 rReq.Done(false);
695 return;
698 // Use provided save file name. If empty determine file name
699 if ( !bHasLocation )
701 // Create a default file name with the correct extension
702 const OUString aPreviewFileName( "webpreview" );
703 aFileName = aPreviewFileName;
705 else
707 // Determine file name from model
708 INetURLObject aFObj( xStorable->getLocation() );
709 aFileName = aFObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::NO_DECODE );
712 OSL_ASSERT( !aFilterName.isEmpty() );
713 OSL_ASSERT( !aFileName.isEmpty() );
715 // Creates a temporary directory to store our predefined file into it.
716 ::utl::TempFile aTempDir( NULL, true );
718 INetURLObject aFilePathObj( aTempDir.GetURL() );
719 aFilePathObj.insertName( aFileName );
720 aFilePathObj.setExtension( aExtension );
722 OUString aFileURL = aFilePathObj.GetMainURL( INetURLObject::NO_DECODE );
724 css::uno::Sequence< css::beans::PropertyValue > aArgs( 1 );
725 aArgs[0].Name = "FilterName";
726 aArgs[0].Value = css::uno::makeAny( aFilterName );
728 // Store document in the html format
731 xStorable->storeToURL( aFileURL, aArgs );
733 catch (const io::IOException&)
735 rReq.Done(false);
736 return;
739 rReq.Done(sfx2::openUriExternally(aFileURL, true));
740 break;
742 else
744 rReq.Done(false);
745 return;
749 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
750 case SID_PLUGINS_ACTIVE:
752 SFX_REQUEST_ARG(rReq, pShowItem, SfxBoolItem, nId, false);
753 bool const bActive = (pShowItem)
754 ? pShowItem->GetValue()
755 : !pImp->m_bPlugInsActive;
756 // ggf. recorden
757 if ( !rReq.IsAPI() )
758 rReq.AppendItem( SfxBoolItem( nId, bActive ) );
760 // Jetzt schon DONE aufrufen, da die Argumente evtl. einen Pool
761 // benutzen, der demn"achst weg ist
762 rReq.Done(true);
764 // ausfuehren
765 if (!pShowItem || (bActive != pImp->m_bPlugInsActive))
767 SfxFrame* pTopFrame = &GetFrame()->GetTopFrame();
768 if ( pTopFrame != &GetFrame()->GetFrame() )
770 // FramesetDocument
771 SfxViewShell *pShell = pTopFrame->GetCurrentViewFrame()->GetViewShell();
772 if ( pShell->GetInterface()->GetSlot( nId ) )
773 pShell->ExecuteSlot( rReq );
774 break;
777 SfxFrameIterator aIter( *pTopFrame );
778 while ( pTopFrame )
780 if ( pTopFrame->GetCurrentViewFrame() )
782 SfxViewShell *pView = pTopFrame->GetCurrentViewFrame()->GetViewShell();
783 if ( pView )
785 pView->pImp->m_bPlugInsActive = bActive;
786 Rectangle aVisArea = GetObjectShell()->GetVisArea();
787 VisAreaChanged(aVisArea);
789 // the plugins might need change in their state
790 SfxInPlaceClientList *pClients = pView->pImp->GetIPClientList_Impl(false);
791 if ( pClients )
793 for ( size_t n = 0; n < pClients->size(); n++)
795 SfxInPlaceClient* pIPClient = pClients->at( n );
796 if ( pIPClient )
797 pView->CheckIPClient_Impl( pIPClient, aVisArea );
803 if ( !pTopFrame->GetParentFrame() )
804 pTopFrame = aIter.FirstFrame();
805 else
806 pTopFrame = aIter.NextFrame( *pTopFrame );
810 break;
817 void SfxViewShell::GetState_Impl( SfxItemSet &rSet )
820 SfxWhichIter aIter( rSet );
821 for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() )
823 switch ( nSID )
825 #if HAVE_FEATURE_MACOSX_SANDBOX
826 case SID_BLUETOOTH_SENDDOC:
827 case SID_MAIL_SENDDOC:
828 case SID_MAIL_SENDDOCASFORMAT:
829 case SID_MAIL_SENDDOCASMS:
830 case SID_MAIL_SENDDOCASOOO:
831 case SID_MAIL_SENDDOCASPDF:
832 rSet.DisableItem(nSID);
833 break;
834 #endif
835 // Printer functions
836 case SID_PRINTDOC:
837 case SID_PRINTDOCDIRECT:
838 case SID_SETUPPRINTER:
839 case SID_PRINTER_NAME:
841 bool bEnabled = pImp->m_bCanPrint && !pImp->m_nPrinterLocks;
842 bEnabled = bEnabled && !Application::GetSettings().GetMiscSettings().GetDisablePrinting();
843 if ( bEnabled )
845 SfxPrinter *pPrinter = GetPrinter(false);
847 if ( SID_PRINTDOCDIRECT == nSID )
849 OUString aPrinterName;
850 if ( pPrinter != NULL )
851 aPrinterName = pPrinter->GetName();
852 else
853 aPrinterName = Printer::GetDefaultPrinterName();
854 if ( !aPrinterName.isEmpty() )
856 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
858 OUStringBuffer aBuffer( 60 );
859 aBuffer.append( RetrieveLabelFromCommand(
860 OUString( ".uno:PrintDefault" ),
861 xFrame ));
862 aBuffer.append( " (" );
863 aBuffer.append( aPrinterName );
864 aBuffer.append(')');
866 rSet.Put( SfxStringItem( SID_PRINTDOCDIRECT, aBuffer.makeStringAndClear() ) );
869 bEnabled = !pPrinter || !pPrinter->IsPrinting();
871 break;
874 // PlugIns running
875 case SID_PLUGINS_ACTIVE:
877 rSet.Put( SfxBoolItem( SID_PLUGINS_ACTIVE, !pImp->m_bPlugInsActive) );
878 break;
880 case SID_STYLE_FAMILY :
882 rSet.Put( SfxUInt16Item( SID_STYLE_FAMILY, pImp->m_nFamily ) );
883 break;
891 void SfxViewShell::SetZoomFactor( const Fraction &rZoomX,
892 const Fraction &rZoomY )
894 DBG_ASSERT( GetWindow(), "no window" );
895 MapMode aMap( GetWindow()->GetMapMode() );
896 aMap.SetScaleX( rZoomX );
897 aMap.SetScaleY( rZoomY );
898 GetWindow()->SetMapMode( aMap );
902 ErrCode SfxViewShell::DoVerb(long /*nVerb*/)
904 /* [Description]
906 Virtual Method used to perform a Verb on a selected Object.
907 Since this Object is only known by the derived classes, they must override
908 DoVerb.
912 return ERRCODE_SO_NOVERBS;
917 void SfxViewShell::OutplaceActivated( bool bActive, SfxInPlaceClient* /*pClient*/ )
919 if ( !bActive )
920 GetFrame()->GetFrame().Appear();
925 void SfxViewShell::UIActivating( SfxInPlaceClient* /*pClient*/ )
927 uno::Reference < frame::XFrame > xOwnFrame( pFrame->GetFrame().GetFrameInterface() );
928 uno::Reference < frame::XFramesSupplier > xParentFrame( xOwnFrame->getCreator(), uno::UNO_QUERY );
929 if ( xParentFrame.is() )
930 xParentFrame->setActiveFrame( xOwnFrame );
932 pFrame->GetBindings().HidePopups(true);
933 pFrame->GetDispatcher()->Update_Impl( true );
938 void SfxViewShell::UIDeactivated( SfxInPlaceClient* /*pClient*/ )
940 if ( !pFrame->GetFrame().IsClosing_Impl() || SfxViewFrame::Current() != pFrame )
941 pFrame->GetDispatcher()->Update_Impl( true );
942 pFrame->GetBindings().HidePopups(false);
944 pFrame->GetBindings().InvalidateAll(true);
949 SfxInPlaceClient* SfxViewShell::FindIPClient
951 const uno::Reference < embed::XEmbeddedObject >& xObj,
952 vcl::Window* pObjParentWin
953 ) const
955 SfxInPlaceClientList *pClients = pImp->GetIPClientList_Impl(false);
956 if ( !pClients )
957 return 0;
959 if( !pObjParentWin )
960 pObjParentWin = GetWindow();
961 for ( size_t n = 0; n < pClients->size(); n++)
963 SfxInPlaceClient *pIPClient = pClients->at( n );
964 if ( pIPClient->GetObject() == xObj && pIPClient->GetEditWin() == pObjParentWin )
965 return pIPClient;
968 return 0;
973 SfxInPlaceClient* SfxViewShell::GetIPClient() const
975 return GetUIActiveClient();
980 SfxInPlaceClient* SfxViewShell::GetUIActiveIPClient_Impl() const
982 // this method is needed as long as SFX still manages the border space for ChildWindows (see SfxFrame::Resize)
983 SfxInPlaceClientList *pClients = pImp->GetIPClientList_Impl(false);
984 if ( !pClients )
985 return 0;
987 for ( size_t n = 0; n < pClients->size(); n++)
989 SfxInPlaceClient* pIPClient = pClients->at( n );
990 if ( pIPClient->IsUIActive() )
991 return pIPClient;
994 return NULL;
997 SfxInPlaceClient* SfxViewShell::GetUIActiveClient() const
999 SfxInPlaceClientList *pClients = pImp->GetIPClientList_Impl(false);
1000 if ( !pClients )
1001 return 0;
1003 for ( size_t n = 0; n < pClients->size(); n++)
1005 SfxInPlaceClient* pIPClient = pClients->at( n );
1006 if ( pIPClient->IsObjectUIActive() )
1007 return pIPClient;
1010 return NULL;
1015 void SfxViewShell::Activate( bool bMDI )
1017 if ( bMDI )
1019 SfxObjectShell *pSh = GetViewFrame()->GetObjectShell();
1020 if ( pSh->GetModel().is() )
1021 pSh->GetModel()->setCurrentController( GetViewFrame()->GetFrame().GetController() );
1023 SetCurrentDocument();
1029 void SfxViewShell::Deactivate(bool /*bMDI*/)
1035 void SfxViewShell::AdjustPosSizePixel
1037 const Point& /*rToolOffset*/,// Upper left corner Tools in Frame-Window
1038 const Size& /*rSize*/ // All available sizes.
1046 void SfxViewShell::Move()
1048 /* [Description]
1050 This virtual Method is called when the window displayed in the
1051 SfxViewShell gets a StarView-Move() notification.
1053 This base implementation does not have to be called. .
1055 [Note]
1057 This Method can be used to cancel a selection, in order to catch the
1058 mouse movement which is due to moving a window.
1060 For now the notification does not work In-Place.
1068 void SfxViewShell::OuterResizePixel
1070 const Point& /*rToolOffset*/,// Upper left corner Tools in Frame-Window
1071 const Size& /*rSize*/ // All available sizes.
1074 /* [Description]
1076 Override this Method to be able to react to the size-change of
1077 the View. Thus the View is defined as the Edit window and also the
1078 attached Tools are defined (for example the ruler).
1080 The Edit window must not be changed either in size or position.
1082 The Vis-Area of SfxObjectShell, its scale and position can be changed
1083 here. The mainuse is to change the size of the Vis-Area.
1085 If the Border is changed due to the new calculation then this has to be set
1086 by <SfxViewShell::SetBorderPixel(const SvBorder&)>. The Positioning of Tools
1087 is only allowed after the calling of 'SetBorderPixel'.
1089 [Example]
1091 void AppViewSh::OuterViewResizePixel( const Point &rOfs, const Size &rSz )
1093 // Calculate Tool position and size externally, do not set!
1094 // (due to the following Border calculation)
1095 Point aHLinPos...; Size aHLinSz...;
1098 // Calculate and Set a Border of Tools which matches rSize.
1099 SvBorder aBorder...
1100 SetBorderPixel( aBorder ); // Allow Positioning from here on.
1102 // Arrange Tools
1103 pHLin->SetPosSizePixel( aHLinPos, aHLinSz );
1107 [Cross-reference]
1109 <SfxViewShell::InnerResizePixel(const Point&,const Size& rSize)>
1113 SetBorderPixel( SvBorder() );
1118 void SfxViewShell::InnerResizePixel
1120 const Point& /*rToolOffset*/,// Upper left corner Tools in Frame-Window
1121 const Size& /*rSize*/ // All available sizes.
1124 /* [Description]
1126 Override this Method to be able to react to the size-change of
1127 the Edit window.
1129 The Edit window must not be changed either in size or position.
1130 Neither the Vis-Area of SfxObjectShell nor its scale or position are
1131 allowed to be changed
1133 If the Border is changed due to the new calculation then is has to be set
1134 by <SfxViewShell::SetBorderPixel(const SvBorder&)>.
1135 The Positioning of Tools is only allowed after the calling of
1136 'SetBorderPixel'.
1139 [Note]
1141 void AppViewSh::InnerViewResizePixel( const Point &rOfs, const Size &rSz )
1143 // Calculate Tool position and size internally, do not set!
1144 // (due to the following Border calculation)
1145 Point aHLinPos...; Size aHLinSz...;
1148 // Calculate and Set a Border of Tools which matches rSize.
1149 SvBorder aBorder...
1150 SetBorderPixel( aBorder ); // Allow Positioning from here on.
1152 // Arrange Tools
1153 pHLin->SetPosSizePixel( aHLinPos, aHLinSz );
1157 [Cross-reference]
1159 <SfxViewShell::OuterResizePixel(const Point&,const Size& rSize)>
1163 SetBorderPixel( SvBorder() );
1168 void SfxViewShell::InvalidateBorder()
1170 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" );
1172 GetViewFrame()->InvalidateBorderImpl( this );
1173 if (pImp->m_pController.is())
1175 pImp->m_pController->BorderWidthsChanged_Impl();
1181 void SfxViewShell::SetBorderPixel( const SvBorder &rBorder )
1183 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" );
1185 GetViewFrame()->SetBorderPixelImpl( this, rBorder );
1187 // notify related controller that border size is changed
1188 if (pImp->m_pController.is())
1190 pImp->m_pController->BorderWidthsChanged_Impl();
1196 const SvBorder& SfxViewShell::GetBorderPixel() const
1198 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" );
1200 return GetViewFrame()->GetBorderPixelImpl( this );
1205 void SfxViewShell::SetWindow
1207 vcl::Window* pViewPort // For example Null pointer in the Destructor.
1210 /* [Description]
1212 With this method the SfxViewShell is set in the data window. This is
1213 needed for the in-place container and for restoring the proper focus.
1215 Even in-place-active the conversion of the ViewPort Windows is forbidden.
1219 if( pWindow == pViewPort )
1220 return;
1222 // Disconnect existing IP-Clients if possible
1223 DisconnectAllClients();
1225 //TODO: should we have a "ReconnectAllClients" method?
1226 DiscardClients_Impl();
1228 // Switch View-Port
1229 bool bHadFocus = pWindow && pWindow->HasChildPathFocus( true );
1230 pWindow = pViewPort;
1232 if( pWindow )
1234 // Disable automatic GUI mirroring (right-to-left) for document windows
1235 pWindow->EnableRTL( false );
1238 if ( bHadFocus && pWindow )
1239 pWindow->GrabFocus();
1240 //TODO/CLEANUP
1241 //Do we still need this Method?!
1242 //SfxGetpApp()->GrabFocus( pWindow );
1247 SfxViewShell::SfxViewShell
1249 SfxViewFrame* pViewFrame, /* <SfxViewFrame>, which will be
1250 displayed in this View */
1251 SfxViewShellFlags nFlags /* See <SfxViewShell-Flags> */
1254 : SfxShell(this)
1255 , pImp( new SfxViewShell_Impl(nFlags) )
1256 , pFrame(pViewFrame)
1257 , pSubShell(0)
1258 , pWindow(0)
1259 , bNoNewWindow( nFlags & SfxViewShellFlags::NO_NEWWINDOW )
1260 , mbPrinterSettingsModified(false)
1263 if ( pViewFrame->GetParentViewFrame() )
1265 pImp->m_bPlugInsActive = pViewFrame->GetParentViewFrame()
1266 ->GetViewShell()->pImp->m_bPlugInsActive;
1268 SetMargin( pViewFrame->GetMargin_Impl() );
1270 SetPool( &pViewFrame->GetObjectShell()->GetPool() );
1271 StartListening(*pViewFrame->GetObjectShell());
1273 // Insert into list
1274 SfxViewShellArr_Impl &rViewArr = SfxGetpApp()->GetViewShells_Impl();
1275 rViewArr.push_back(this);
1280 SfxViewShell::~SfxViewShell()
1283 // Remove from list
1284 const SfxViewShell *pThis = this;
1285 SfxViewShellArr_Impl &rViewArr = SfxGetpApp()->GetViewShells_Impl();
1286 SfxViewShellArr_Impl::iterator it = std::find( rViewArr.begin(), rViewArr.end(), pThis );
1287 rViewArr.erase( it );
1289 if ( pImp->xClipboardListener.is() )
1291 pImp->xClipboardListener->DisconnectViewShell();
1292 pImp->xClipboardListener = NULL;
1295 if (pImp->m_pController.is())
1297 pImp->m_pController->ReleaseShell_Impl();
1298 pImp->m_pController.clear();
1301 DELETEZ( pImp );
1304 bool SfxViewShell::PrepareClose
1306 bool bUI // TRUE: Allow Dialog and so on, FALSE: silent-mode
1309 SfxPrinter *pPrinter = GetPrinter();
1310 if ( pPrinter && pPrinter->IsPrinting() )
1312 if ( bUI )
1314 ScopedVclPtrInstance< MessageDialog > aInfoBox(&GetViewFrame()->GetWindow(), SfxResId( STR_CANT_CLOSE ), VCL_MESSAGE_INFO );
1315 aInfoBox->Execute();
1318 return false;
1321 if( GetViewFrame()->IsInModalMode() )
1322 return false;
1324 if( bUI && GetViewFrame()->GetDispatcher()->IsLocked() )
1325 return false;
1327 return true;
1332 SfxViewShell* SfxViewShell::Current()
1334 SfxViewFrame *pCurrent = SfxViewFrame::Current();
1335 return pCurrent ? pCurrent->GetViewShell() : NULL;
1340 SfxViewShell* SfxViewShell::Get( const Reference< XController>& i_rController )
1342 if ( !i_rController.is() )
1343 return NULL;
1345 for ( SfxViewShell* pViewShell = SfxViewShell::GetFirst( NULL, false );
1346 pViewShell;
1347 pViewShell = SfxViewShell::GetNext( *pViewShell, NULL, false )
1350 if ( pViewShell->GetController() == i_rController )
1351 return pViewShell;
1353 return NULL;
1358 SdrView* SfxViewShell::GetDrawView() const
1360 /* [Description]
1362 This virtual Method has to be overloded by the sub classes, to be able
1363 make the Property-Editor available.
1365 The default implementation does always return zero.
1369 return 0;
1374 OUString SfxViewShell::GetSelectionText
1376 bool /*bCompleteWords*/ /* FALSE (default)
1377 Only the actual selected text is returned.
1379 TRUE
1380 The selected text is expanded so that only
1381 whole words are returned. As word separators
1382 these are used: white spaces and punctuation
1383 ".,;" and single and double quotes.
1387 /* [Description]
1389 Override this Method to return a text that
1390 is included in the current selection. This is for example used when
1391 sending emails.
1393 When called with "CompleteWords == TRUE", it is for example sufficient
1394 with having the Cursor positioned somewhere within an URL in-order
1395 to have the entire URL returned.
1399 return OUString();
1404 bool SfxViewShell::HasSelection( bool ) const
1406 /* [Description]
1408 With this virtual Method can a for example a Dialog be queried, to
1409 check if something is selected in the current view. If the Parameter
1410 is <BOOL> TRUE then it is checked whether some text is selected.
1414 return false;
1417 void SfxViewShell::AddSubShell( SfxShell& rShell )
1419 pImp->aArr.push_back(&rShell);
1420 SfxDispatcher *pDisp = pFrame->GetDispatcher();
1421 if ( pDisp->IsActive(*this) )
1423 pDisp->Push(rShell);
1424 pDisp->Flush();
1428 void SfxViewShell::RemoveSubShell( SfxShell* pShell )
1430 SfxDispatcher *pDisp = pFrame->GetDispatcher();
1431 if ( !pShell )
1433 size_t nCount = pImp->aArr.size();
1434 if ( pDisp->IsActive(*this) )
1436 for(size_t n = nCount; n > 0; --n)
1437 pDisp->Pop(*pImp->aArr[n - 1]);
1438 pDisp->Flush();
1440 pImp->aArr.clear();
1442 else
1444 SfxShellArr_Impl::iterator i = std::find(pImp->aArr.begin(), pImp->aArr.end(), pShell);
1445 if(i != pImp->aArr.end())
1447 pImp->aArr.erase(i);
1448 if(pDisp->IsActive(*this))
1450 pDisp->RemoveShell_Impl(*pShell);
1451 pDisp->Flush();
1457 SfxShell* SfxViewShell::GetSubShell( sal_uInt16 nNo )
1459 sal_uInt16 nCount = pImp->aArr.size();
1460 if(nNo < nCount)
1461 return pImp->aArr[nCount - nNo - 1];
1462 return NULL;
1465 void SfxViewShell::PushSubShells_Impl( bool bPush )
1467 SfxDispatcher *pDisp = pFrame->GetDispatcher();
1468 if ( bPush )
1470 for(SfxShellArr_Impl::const_iterator i = pImp->aArr.begin(); i != pImp->aArr.end(); ++i)
1471 pDisp->Push(**i);
1473 else if(!pImp->aArr.empty())
1475 SfxShell& rPopUntil = *pImp->aArr[0];
1476 if ( pDisp->GetShellLevel( rPopUntil ) != USHRT_MAX )
1477 pDisp->Pop( rPopUntil, SfxDispatcherPopFlags::POP_UNTIL );
1480 pDisp->Flush();
1485 void SfxViewShell::WriteUserData( OUString&, bool )
1491 void SfxViewShell::ReadUserData(const OUString&, bool )
1495 void SfxViewShell::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue >&, bool )
1499 void SfxViewShell::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >&, bool )
1505 // returns the first shell of spec. type viewing the specified doc.
1507 SfxViewShell* SfxViewShell::GetFirst
1509 const TypeId* pType,
1510 bool bOnlyVisible
1513 // search for a SfxViewShell of the specified type
1514 SfxViewShellArr_Impl &rShells = SfxGetpApp()->GetViewShells_Impl();
1515 SfxViewFrameArr_Impl &rFrames = SfxGetpApp()->GetViewFrames_Impl();
1516 for ( sal_uInt16 nPos = 0; nPos < rShells.size(); ++nPos )
1518 SfxViewShell *pShell = rShells[nPos];
1519 if ( pShell )
1521 // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame
1522 // these ViewShells shouldn't be accessible anymore
1523 // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps
1524 for ( sal_uInt16 n=0; n<rFrames.size(); ++n )
1526 SfxViewFrame *pFrame = rFrames[n];
1527 if ( pFrame == pShell->GetViewFrame() )
1529 // only ViewShells with a valid ViewFrame will be returned
1530 if ( ( !bOnlyVisible || pFrame->IsVisible() ) && ( !pType || pShell->IsA(*pType) ) )
1531 return pShell;
1532 break;
1538 return 0;
1542 // returns the next shell of spec. type viewing the specified doc.
1544 SfxViewShell* SfxViewShell::GetNext
1546 const SfxViewShell& rPrev,
1547 const TypeId* pType,
1548 bool bOnlyVisible
1551 SfxViewShellArr_Impl &rShells = SfxGetpApp()->GetViewShells_Impl();
1552 SfxViewFrameArr_Impl &rFrames = SfxGetpApp()->GetViewFrames_Impl();
1553 sal_uInt16 nPos;
1554 for ( nPos = 0; nPos < rShells.size(); ++nPos )
1555 if ( rShells[nPos] == &rPrev )
1556 break;
1558 for ( ++nPos; nPos < rShells.size(); ++nPos )
1560 SfxViewShell *pShell = rShells[nPos];
1561 if ( pShell )
1563 // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame
1564 // these ViewShells shouldn't be accessible anymore
1565 // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps
1566 for ( sal_uInt16 n=0; n<rFrames.size(); ++n )
1568 SfxViewFrame *pFrame = rFrames[n];
1569 if ( pFrame == pShell->GetViewFrame() )
1571 // only ViewShells with a valid ViewFrame will be returned
1572 if ( ( !bOnlyVisible || pFrame->IsVisible() ) && ( !pType || pShell->IsA(*pType) ) )
1573 return pShell;
1574 break;
1580 return 0;
1585 void SfxViewShell::Notify( SfxBroadcaster& rBC,
1586 const SfxHint& rHint )
1588 const SfxEventHint* pEventHint = dynamic_cast<const SfxEventHint*>(&rHint);
1589 if ( pEventHint )
1591 switch ( pEventHint->GetEventId() )
1593 case SFX_EVENT_LOADFINISHED:
1595 if ( GetController().is() )
1597 // avoid access to dangling ViewShells
1598 SfxViewFrameArr_Impl &rFrames = SfxGetpApp()->GetViewFrames_Impl();
1599 for ( sal_uInt16 n=0; n<rFrames.size(); ++n )
1601 SfxViewFrame *frame = rFrames[n];
1602 if ( frame == GetViewFrame() && &rBC == GetObjectShell() )
1604 SfxItemSet* pSet = GetObjectShell()->GetMedium()->GetItemSet();
1605 SFX_ITEMSET_ARG( pSet, pItem, SfxUnoAnyItem, SID_VIEW_DATA, false );
1606 if ( pItem )
1608 pImp->m_pController->restoreViewData( pItem->GetValue() );
1609 pSet->ClearItem( SID_VIEW_DATA );
1612 break;
1617 break;
1623 bool SfxViewShell::ExecKey_Impl(const KeyEvent& aKey)
1625 if (!pImp->m_xAccExec.get())
1627 pImp->m_xAccExec.reset(
1628 ::svt::AcceleratorExecute::createAcceleratorHelper() );
1629 pImp->m_xAccExec->init(::comphelper::getProcessComponentContext(),
1630 pFrame->GetFrame().GetFrameInterface());
1633 return pImp->m_xAccExec->execute(aKey.GetKeyCode());
1636 bool SfxViewShell::KeyInput( const KeyEvent &rKeyEvent )
1638 /* [Description]
1640 This Method executes the KeyEvent 'rKeyEvent' of the Keys (Accelerator)
1641 configured either direct or indirect (for example by the Application)
1642 in the SfxViewShell.
1644 [Return value]
1646 bool TRUE
1647 The Key (Accelerator) is configured and the
1648 the associated Handler was called
1650 FALSE
1651 The Key (Accelerator) is not configured and
1652 subsequently no Handler was called
1654 [Cross-reference]
1656 <SfxApplication::KeyInput(const KeyEvent&)>
1659 return ExecKey_Impl(rKeyEvent);
1662 bool SfxViewShell::GlobalKeyInput_Impl( const KeyEvent &rKeyEvent )
1664 return ExecKey_Impl(rKeyEvent);
1669 void SfxViewShell::ShowCursor( bool /*bOn*/ )
1671 /* [Description]
1673 Subclasses must override this Method so that SFx can switch the
1674 Cursor on and off, for example while a <SfxProgress> is running.
1682 void SfxViewShell::ResetAllClients_Impl( SfxInPlaceClient *pIP )
1685 SfxInPlaceClientList *pClients = pImp->GetIPClientList_Impl(false);
1686 if ( !pClients )
1687 return;
1689 for ( size_t n = 0; n < pClients->size(); n++ )
1691 SfxInPlaceClient* pIPClient = pClients->at( n );
1692 if( pIPClient != pIP )
1693 pIPClient->ResetObject();
1699 void SfxViewShell::DisconnectAllClients()
1701 SfxInPlaceClientList *pClients = pImp->GetIPClientList_Impl(false);
1702 if ( !pClients )
1703 return;
1705 for ( size_t n = 0; n < pClients->size(); )
1706 // clients will remove themselves from the list
1707 delete pClients->at( n );
1712 void SfxViewShell::QueryObjAreaPixel( Rectangle& ) const
1718 void SfxViewShell::VisAreaChanged(const Rectangle& /*rVisArea*/)
1720 SfxInPlaceClientList *pClients = pImp->GetIPClientList_Impl(false);
1721 if ( !pClients )
1722 return;
1724 for ( size_t n = 0; n < pClients->size(); n++)
1726 SfxInPlaceClient* pIPClient = pClients->at( n );
1727 if ( pIPClient->IsObjectInPlaceActive() )
1728 // client is active, notify client that the VisArea might have changed
1729 pIPClient->VisAreaChanged();
1734 void SfxViewShell::CheckIPClient_Impl( SfxInPlaceClient *pIPClient, const Rectangle& rVisArea )
1736 if ( GetObjectShell()->IsInClose() )
1737 return;
1739 bool bAlwaysActive =
1740 ( ( pIPClient->GetObjectMiscStatus() & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY ) != 0 );
1741 bool bActiveWhenVisible =
1742 ( (( pIPClient->GetObjectMiscStatus() & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE ) != 0 ) ||
1743 svt::EmbeddedObjectRef::IsGLChart(pIPClient->GetObject()));
1745 // this method is called when either a client is created or the "Edit/Plugins" checkbox is checked
1746 if ( !pIPClient->IsObjectInPlaceActive() && pImp->m_bPlugInsActive )
1748 // object in client is currently not active
1749 // check if the object wants to be activated always or when it becomes at least partially visible
1750 // TODO/LATER: maybe we should use the scaled area instead of the ObjArea?!
1751 if ( bAlwaysActive || (bActiveWhenVisible && rVisArea.IsOver(pIPClient->GetObjArea())) )
1755 pIPClient->GetObject()->changeState( embed::EmbedStates::INPLACE_ACTIVE );
1757 catch (const uno::Exception&)
1762 else if (!pImp->m_bPlugInsActive)
1764 // object in client is currently active and "Edit/Plugins" checkbox is selected
1765 // check if the object wants to be activated always or when it becomes at least partially visible
1766 // in this case selecting of the "Edit/Plugin" checkbox should let such objects deactivate
1767 if ( bAlwaysActive || bActiveWhenVisible )
1768 pIPClient->GetObject()->changeState( embed::EmbedStates::RUNNING );
1773 void SfxViewShell::DiscardClients_Impl()
1775 /* [Description]
1777 The purpose of this Method is to prevent the saving of Objects when closing
1778 the Document, if the user has chosen to close without saving.
1782 SfxInPlaceClientList *pClients = pImp->GetIPClientList_Impl(false);
1783 if ( !pClients )
1784 return;
1786 for ( size_t n = 0; n < pClients->size(); )
1787 delete pClients->at( n );
1792 SfxObjectShell* SfxViewShell::GetObjectShell()
1794 return pFrame ? pFrame->GetObjectShell() : NULL;
1799 Reference< XModel > SfxViewShell::GetCurrentDocument() const
1801 Reference< XModel > xDocument;
1803 const SfxObjectShell* pDocShell( const_cast< SfxViewShell* >( this )->GetObjectShell() );
1804 OSL_ENSURE( pDocShell, "SfxViewFrame::GetCurrentDocument: no DocShell!?" );
1805 if ( pDocShell )
1806 xDocument = pDocShell->GetModel();
1807 return xDocument;
1812 void SfxViewShell::SetCurrentDocument() const
1814 uno::Reference< frame::XModel > xDocument( GetCurrentDocument() );
1815 if ( xDocument.is() )
1816 SfxObjectShell::SetCurrentComponent( xDocument );
1821 const Size& SfxViewShell::GetMargin() const
1823 return pImp->aMargin;
1828 void SfxViewShell::SetMargin( const Size& rSize )
1830 // the default margin was verified using www.apple.com !!
1831 Size aMargin = rSize;
1832 if ( aMargin.Width() == -1 )
1833 aMargin.Width() = DEFAULT_MARGIN_WIDTH;
1834 if ( aMargin.Height() == -1 )
1835 aMargin.Height() = DEFAULT_MARGIN_HEIGHT;
1837 if ( aMargin != pImp->aMargin )
1839 pImp->aMargin = aMargin;
1840 MarginChanged();
1844 void SfxViewShell::MarginChanged()
1848 bool SfxViewShell::IsShowView_Impl() const
1850 return pImp->m_bIsShowView;
1853 void SfxViewShell::JumpToMark( const OUString& rMark )
1855 SfxStringItem aMarkItem( SID_JUMPTOMARK, rMark );
1856 GetViewFrame()->GetDispatcher()->Execute(
1857 SID_JUMPTOMARK,
1858 SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
1859 &aMarkItem, 0L );
1862 void SfxViewShell::SetController( SfxBaseController* pController )
1864 pImp->m_pController = pController;
1865 pImp->m_bControllerSet = true;
1867 // there should be no old listener, but if there is one, it should be disconnected
1868 if ( pImp->xClipboardListener.is() )
1869 pImp->xClipboardListener->DisconnectViewShell();
1871 pImp->xClipboardListener = new SfxClipboardChangeListener( this, GetClipboardNotifier() );
1874 Reference < XController > SfxViewShell::GetController()
1876 return pImp->m_pController.get();
1879 SfxBaseController* SfxViewShell::GetBaseController_Impl() const
1881 return pImp->m_pController.get();
1884 void SfxViewShell::AddContextMenuInterceptor_Impl( const uno::Reference< ui::XContextMenuInterceptor >& xInterceptor )
1886 pImp->aInterceptorContainer.addInterface( xInterceptor );
1889 void SfxViewShell::RemoveContextMenuInterceptor_Impl( const uno::Reference< ui::XContextMenuInterceptor >& xInterceptor )
1891 pImp->aInterceptorContainer.removeInterface( xInterceptor );
1894 void Change( Menu* pMenu, SfxViewShell* pView )
1896 SfxDispatcher *pDisp = pView->GetViewFrame()->GetDispatcher();
1897 sal_uInt16 nCount = pMenu->GetItemCount();
1898 for ( sal_uInt16 nPos=0; nPos<nCount; ++nPos )
1900 sal_uInt16 nId = pMenu->GetItemId(nPos);
1901 OUString aCmd = pMenu->GetItemCommand(nId);
1902 PopupMenu* pPopup = pMenu->GetPopupMenu(nId);
1903 if ( pPopup )
1905 Change( pPopup, pView );
1907 else if ( nId < 5000 )
1909 if ( aCmd.startsWith(".uno:") )
1911 for (sal_uInt16 nIdx=0;;)
1913 SfxShell *pShell=pDisp->GetShell(nIdx++);
1914 if (pShell == NULL)
1915 break;
1916 const SfxInterface *pIFace = pShell->GetInterface();
1917 const SfxSlot* pSlot = pIFace->GetSlot( aCmd );
1918 if ( pSlot )
1920 pMenu->InsertItem( pSlot->GetSlotId(), pMenu->GetItemText( nId ),
1921 pMenu->GetItemBits( nId ), OString(), nPos );
1922 pMenu->SetItemCommand( pSlot->GetSlotId(), aCmd );
1923 pMenu->RemoveItem( nPos+1 );
1924 break;
1933 bool SfxViewShell::TryContextMenuInterception( Menu& rIn, const OUString& rMenuIdentifier, Menu*& rpOut, ui::ContextMenuExecuteEvent aEvent )
1935 rpOut = NULL;
1936 bool bModified = false;
1938 // create container from menu
1939 aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
1940 &rIn, &rMenuIdentifier );
1942 // get selection from controller
1943 aEvent.Selection = uno::Reference < view::XSelectionSupplier > ( GetController(), uno::UNO_QUERY );
1945 // call interceptors
1946 ::cppu::OInterfaceIteratorHelper aIt( pImp->aInterceptorContainer );
1947 while( aIt.hasMoreElements() )
1951 ui::ContextMenuInterceptorAction eAction =
1952 static_cast<ui::XContextMenuInterceptor*>(aIt.next())->notifyContextMenuExecute( aEvent );
1953 switch ( eAction )
1955 case ui::ContextMenuInterceptorAction_CANCELLED :
1956 // interceptor does not want execution
1957 return false;
1958 case ui::ContextMenuInterceptorAction_EXECUTE_MODIFIED :
1959 // interceptor wants his modified menu to be executed
1960 bModified = true;
1961 break;
1962 case ui::ContextMenuInterceptorAction_CONTINUE_MODIFIED :
1963 // interceptor has modified menu, but allows for calling other interceptors
1964 bModified = true;
1965 continue;
1966 case ui::ContextMenuInterceptorAction_IGNORED :
1967 // interceptor is indifferent
1968 continue;
1969 default:
1970 OSL_FAIL("Wrong return value of ContextMenuInterceptor!");
1971 continue;
1974 catch (...)
1976 aIt.remove();
1979 break;
1982 if ( bModified )
1984 // container was modified, create a new window out of it
1985 rpOut = new PopupMenu;
1986 ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer( rpOut, aEvent.ActionTriggerContainer );
1988 Change( rpOut, this );
1991 return true;
1994 void SfxViewShell::TakeOwnership_Impl()
1996 // currently there is only one reason to take Ownership: a hidden frame is printed
1997 // so the ViewShell will check this on EndPrint (->prnmon.cxx)
1998 pImp->m_bGotOwnership = true;
2001 void SfxViewShell::TakeFrameOwnership_Impl()
2003 // currently there is only one reason to take Ownership: a hidden frame is printed
2004 // so the ViewShell will check this on EndPrint (->prnmon.cxx)
2005 pImp->m_bGotFrameOwnership = true;
2008 bool SfxViewShell::HandleNotifyEvent_Impl( NotifyEvent& rEvent )
2010 if (pImp->m_pController.is())
2011 return pImp->m_pController->HandleEvent_Impl( rEvent );
2012 return false;
2015 bool SfxViewShell::HasKeyListeners_Impl()
2017 return (pImp->m_pController.is())
2018 && pImp->m_pController->HasKeyListeners_Impl();
2021 bool SfxViewShell::HasMouseClickListeners_Impl()
2023 return (pImp->m_pController.is())
2024 && pImp->m_pController->HasMouseClickListeners_Impl();
2027 bool SfxViewShell::Escape()
2029 return GetViewFrame()->GetBindings().Execute( SID_TERMINATE_INPLACEACTIVATION );
2032 Reference< view::XRenderable > SfxViewShell::GetRenderable()
2034 Reference< view::XRenderable >xRender;
2035 SfxObjectShell* pObj = GetObjectShell();
2036 if( pObj )
2038 Reference< frame::XModel > xModel( pObj->GetModel() );
2039 if( xModel.is() )
2040 xRender = Reference< view::XRenderable >( xModel, UNO_QUERY );
2042 return xRender;
2045 uno::Reference< datatransfer::clipboard::XClipboardNotifier > SfxViewShell::GetClipboardNotifier()
2047 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClipboardNotifier;
2048 if ( GetViewFrame() )
2049 xClipboardNotifier = uno::Reference< datatransfer::clipboard::XClipboardNotifier >(
2050 GetViewFrame()->GetWindow().GetClipboard(), uno::UNO_QUERY );
2052 return xClipboardNotifier;
2055 void SfxViewShell::AddRemoveClipboardListener( const uno::Reference < datatransfer::clipboard::XClipboardListener >& rClp, bool bAdd )
2059 if ( GetViewFrame() )
2061 uno::Reference< datatransfer::clipboard::XClipboard > xClipboard( GetViewFrame()->GetWindow().GetClipboard() );
2062 if( xClipboard.is() )
2064 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClpbrdNtfr( xClipboard, uno::UNO_QUERY );
2065 if( xClpbrdNtfr.is() )
2067 if( bAdd )
2068 xClpbrdNtfr->addClipboardListener( rClp );
2069 else
2070 xClpbrdNtfr->removeClipboardListener( rClp );
2075 catch (const uno::Exception&)
2080 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */