Bump version to 4.1-6
[LibreOffice.git] / sfx2 / source / view / viewsh.cxx
blob0ac1b2093c16218e008f144a746c81b9f0a6b4ef
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 <svl/stritem.hxx>
21 #include <svl/eitem.hxx>
22 #include <svl/whiter.hxx>
23 #include <vcl/msgbox.hxx>
24 #include <vcl/toolbox.hxx>
25 #include <svl/intitem.hxx>
26 #include <svtools/sfxecode.hxx>
27 #include <svtools/ehdl.hxx>
28 #include <com/sun/star/frame/XLayoutManager.hpp>
29 #include <com/sun/star/frame/ModuleManager.hpp>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/embed/EmbedStates.hpp>
32 #include <com/sun/star/embed/EmbedMisc.hpp>
33 #include <com/sun/star/container/XContainerQuery.hpp>
34 #include <com/sun/star/frame/XStorable.hpp>
35 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
36 #include <com/sun/star/frame/UICommandDescription.hpp>
37 #include <cppuhelper/implbase1.hxx>
39 #include <osl/file.hxx>
40 #include <osl/mutex.hxx>
41 #include <tools/urlobj.hxx>
42 #include <unotools/tempfile.hxx>
43 #include <unotools/pathoptions.hxx>
44 #include <svtools/miscopt.hxx>
45 #include <svtools/soerr.hxx>
47 #include <basic/basmgr.hxx>
48 #include <basic/sbuno.hxx>
49 #include <framework/actiontriggerhelper.hxx>
50 #include <comphelper/processfactory.hxx>
51 #include <comphelper/sequenceashashmap.hxx>
52 #include <toolkit/unohlp.hxx>
55 #include <sfx2/app.hxx>
56 #include "view.hrc"
57 #include <sfx2/viewsh.hxx>
58 #include "viewimp.hxx"
59 #include "sfx2/sfxresid.hxx"
60 #include <sfx2/request.hxx>
61 #include <sfx2/templdlg.hxx>
62 #include <sfx2/printer.hxx>
63 #include <sfx2/docfile.hxx>
64 #include <sfx2/dispatch.hxx>
65 #include "arrdecl.hxx"
66 #include <sfx2/docfac.hxx>
67 #include "sfxlocal.hrc"
68 #include <sfx2/sfxbasecontroller.hxx>
69 #include "sfx2/mailmodelapi.hxx"
70 #include "bluthsndapi.hxx"
71 #include <sfx2/viewfrm.hxx>
72 #include <sfx2/event.hxx>
73 #include <sfx2/fcontnr.hxx>
74 #include <sfx2/ipclient.hxx>
75 #include "workwin.hxx"
76 #include <sfx2/objface.hxx>
77 #include <sfx2/docfilt.hxx>
78 #include "openuriexternally.hxx"
80 using namespace ::com::sun::star;
81 using namespace ::com::sun::star::uno;
82 using namespace ::com::sun::star::frame;
83 using namespace ::com::sun::star::beans;
84 using namespace ::com::sun::star::util;
85 using namespace ::cppu;
87 //=========================================================================
88 DBG_NAME(SfxViewShell)
90 #define SfxViewShell
91 #include "sfxslots.hxx"
93 //=========================================================================
95 class SfxClipboardChangeListener : public ::cppu::WeakImplHelper1<
96 datatransfer::clipboard::XClipboardListener >
98 public:
99 SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr );
100 virtual ~SfxClipboardChangeListener();
102 // XEventListener
103 virtual void SAL_CALL disposing( const lang::EventObject& rEventObject )
104 throw ( uno::RuntimeException );
106 // XClipboardListener
107 virtual void SAL_CALL changedContents( const datatransfer::clipboard::ClipboardEvent& rEventObject )
108 throw ( uno::RuntimeException );
110 void DisconnectViewShell() { m_pViewShell = NULL; }
111 void ChangedContents();
113 enum AsyncExecuteCmd
115 ASYNCEXECUTE_CMD_DISPOSING,
116 ASYNCEXECUTE_CMD_CHANGEDCONTENTS
119 struct AsyncExecuteInfo
121 AsyncExecuteInfo( AsyncExecuteCmd eCmd, uno::Reference< datatransfer::clipboard::XClipboardListener > xThis, SfxClipboardChangeListener* pListener ) :
122 m_eCmd( eCmd ), m_xThis( xThis ), m_pListener( pListener ) {}
124 AsyncExecuteCmd m_eCmd;
125 uno::Reference< datatransfer::clipboard::XClipboardListener > m_xThis;
126 SfxClipboardChangeListener* m_pListener;
129 private:
130 SfxViewShell* m_pViewShell;
131 uno::Reference< datatransfer::clipboard::XClipboardNotifier > m_xClpbrdNtfr;
132 uno::Reference< lang::XComponent > m_xCtrl;
134 DECL_STATIC_LINK( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, AsyncExecuteInfo* );
137 SfxClipboardChangeListener::SfxClipboardChangeListener( SfxViewShell* pView, const uno::Reference< datatransfer::clipboard::XClipboardNotifier >& xClpbrdNtfr )
138 : m_pViewShell( 0 ), m_xClpbrdNtfr( xClpbrdNtfr )
140 m_xCtrl = uno::Reference < lang::XComponent >( pView->GetController(), uno::UNO_QUERY );
141 if ( m_xCtrl.is() )
143 m_xCtrl->addEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this ) ) );
144 m_pViewShell = pView;
146 if ( m_xClpbrdNtfr.is() )
148 m_xClpbrdNtfr->addClipboardListener( uno::Reference< datatransfer::clipboard::XClipboardListener >(
149 static_cast< datatransfer::clipboard::XClipboardListener* >( this )));
153 SfxClipboardChangeListener::~SfxClipboardChangeListener()
157 void SfxClipboardChangeListener::ChangedContents()
159 const SolarMutexGuard aGuard;
160 if( m_pViewShell )
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 );
169 IMPL_STATIC_LINK_NOINSTANCE( SfxClipboardChangeListener, AsyncExecuteHdl_Impl, AsyncExecuteInfo*, pAsyncExecuteInfo )
171 if ( pAsyncExecuteInfo )
173 uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( pAsyncExecuteInfo->m_xThis );
174 if ( pAsyncExecuteInfo->m_pListener )
176 if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_DISPOSING )
177 pAsyncExecuteInfo->m_pListener->DisconnectViewShell();
178 else if ( pAsyncExecuteInfo->m_eCmd == ASYNCEXECUTE_CMD_CHANGEDCONTENTS )
179 pAsyncExecuteInfo->m_pListener->ChangedContents();
182 delete pAsyncExecuteInfo;
184 return 0;
187 void SAL_CALL SfxClipboardChangeListener::disposing( const lang::EventObject& /*rEventObject*/ )
188 throw ( uno::RuntimeException )
190 // Either clipboard or ViewShell is going to be destroyed -> no interest in listening anymore
191 uno::Reference< lang::XComponent > xCtrl( m_xCtrl );
192 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xNotify( m_xClpbrdNtfr );
194 uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( static_cast< datatransfer::clipboard::XClipboardListener* >( this ));
195 if ( xCtrl.is() )
196 xCtrl->removeEventListener( uno::Reference < lang::XEventListener > ( static_cast < lang::XEventListener* >( this )));
197 if ( xNotify.is() )
198 xNotify->removeClipboardListener( xThis );
200 // Make asynchronous call to avoid locking SolarMutex which is the
201 // root for many deadlocks, especially in conjuction with the "Windows"
202 // based single thread apartment clipboard code!
203 AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_DISPOSING, xThis, this );
204 Application::PostUserEvent( STATIC_LINK( 0, SfxClipboardChangeListener, AsyncExecuteHdl_Impl ), pInfo );
207 void SAL_CALL SfxClipboardChangeListener::changedContents( const datatransfer::clipboard::ClipboardEvent& )
208 throw ( RuntimeException )
210 // Make asynchronous call to avoid locking SolarMutex which is the
211 // root for many deadlocks, especially in conjuction with the "Windows"
212 // based single thread apartment clipboard code!
213 uno::Reference< datatransfer::clipboard::XClipboardListener > xThis( static_cast< datatransfer::clipboard::XClipboardListener* >( this ));
214 AsyncExecuteInfo* pInfo = new AsyncExecuteInfo( ASYNCEXECUTE_CMD_CHANGEDCONTENTS, xThis, this );
215 Application::PostUserEvent( STATIC_LINK( 0, SfxClipboardChangeListener, AsyncExecuteHdl_Impl ), pInfo );
218 //=========================================================================
220 static OUString RetrieveLabelFromCommand(
221 const OUString& rCommandURL,
222 const css::uno::Reference< css::frame::XFrame >& rFrame )
224 static css::uno::WeakReference< frame::XModuleManager2 > s_xModuleManager;
225 static css::uno::WeakReference< container::XNameAccess > s_xNameAccess;
227 OUString aLabel;
228 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager( s_xModuleManager );
229 css::uno::Reference< css::container::XNameAccess > xNameAccess( s_xNameAccess );
230 css::uno::Reference< css::uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
234 if ( !xModuleManager.is() )
236 xModuleManager = css::frame::ModuleManager::create(xContext);
237 s_xModuleManager = xModuleManager;
240 OUString aModuleIdentifier = xModuleManager->identify( rFrame );
242 if ( !xNameAccess.is() )
244 xNameAccess = css::uno::Reference< css::container::XNameAccess >(
245 css::frame::UICommandDescription::create(xContext),
246 css::uno::UNO_QUERY_THROW );
247 s_xNameAccess = xNameAccess;
250 css::uno::Any a = xNameAccess->getByName( aModuleIdentifier );
251 css::uno::Reference< css::container::XNameAccess > xUICommands;
252 a >>= xUICommands;
254 OUString aStr;
255 css::uno::Sequence< css::beans::PropertyValue > aPropSeq;
257 a = xUICommands->getByName( rCommandURL );
258 if ( a >>= aPropSeq )
260 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
262 if ( aPropSeq[i].Name == "Label" )
264 aPropSeq[i].Value >>= aStr;
265 break;
268 aLabel = aStr;
271 catch (const css::uno::Exception&)
275 return aLabel;
278 //=========================================================================
279 SfxViewShell_Impl::SfxViewShell_Impl(sal_uInt16 const nFlags)
280 : aInterceptorContainer( aMutex )
281 , m_bControllerSet(false)
282 , m_nPrinterLocks(0)
283 , m_bCanPrint(SFX_VIEW_CAN_PRINT == (nFlags & SFX_VIEW_CAN_PRINT))
284 , m_bHasPrintOptions(
285 SFX_VIEW_HAS_PRINTOPTIONS == (nFlags & SFX_VIEW_HAS_PRINTOPTIONS))
286 , m_bPlugInsActive(true)
287 , m_bIsShowView(SFX_VIEW_NO_SHOW != (nFlags & SFX_VIEW_NO_SHOW))
288 , m_bGotOwnership(false)
289 , m_bGotFrameOwnership(false)
290 , m_nFamily(0xFFFF) // undefined, default set by TemplateDialog
291 , m_pController(0)
292 , m_pAccExec(0)
295 //=========================================================================
296 SFX_IMPL_INTERFACE(SfxViewShell,SfxShell,SfxResId(0))
300 TYPEINIT2(SfxViewShell,SfxShell,SfxListener);
302 //--------------------------------------------------------------------
303 /** search for a filter name dependent on type and module
306 static OUString impl_retrieveFilterNameFromTypeAndModule(
307 const css::uno::Reference< css::container::XContainerQuery >& rContainerQuery,
308 const OUString& rType,
309 const OUString& rModuleIdentifier,
310 const sal_Int32 nFlags )
312 // Retrieve filter from type
313 css::uno::Sequence< css::beans::NamedValue > aQuery( 2 );
314 aQuery[0].Name = OUString( "Type" );
315 aQuery[0].Value = css::uno::makeAny( rType );
316 aQuery[1].Name = OUString( "DocumentService" );
317 aQuery[1].Value = css::uno::makeAny( rModuleIdentifier );
319 css::uno::Reference< css::container::XEnumeration > xEnumeration =
320 rContainerQuery->createSubSetEnumerationByProperties( aQuery );
322 OUString aFoundFilterName;
323 while ( xEnumeration->hasMoreElements() )
325 ::comphelper::SequenceAsHashMap aFilterPropsHM( xEnumeration->nextElement() );
326 OUString aFilterName = aFilterPropsHM.getUnpackedValueOrDefault(
327 OUString("Name"),
328 OUString() );
330 sal_Int32 nFilterFlags = aFilterPropsHM.getUnpackedValueOrDefault(
331 OUString("Flags"),
332 sal_Int32( 0 ) );
334 if ( nFilterFlags & nFlags )
336 aFoundFilterName = aFilterName;
337 break;
341 return aFoundFilterName;
344 //--------------------------------------------------------------------
345 /** search for an internal typename, which map to the current app module
346 and map also to a "family" of file formats as e.g. PDF/MS Doc/OOo Doc.
348 enum ETypeFamily
350 E_MS_DOC,
351 E_OOO_DOC
354 OUString impl_searchFormatTypeForApp(const css::uno::Reference< css::frame::XFrame >& xFrame ,
355 ETypeFamily eTypeFamily)
359 css::uno::Reference< css::uno::XComponentContext > xContext (::comphelper::getProcessComponentContext());
360 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager(css::frame::ModuleManager::create(xContext));
362 OUString sModule = xModuleManager->identify(xFrame);
363 OUString sType ;
365 switch(eTypeFamily)
367 case E_MS_DOC:
369 if ( sModule == "com.sun.star.text.TextDocument" )
370 sType = OUString( "writer_MS_Word_97" );
371 else
372 if ( sModule == "com.sun.star.sheet.SpreadsheetDocument" )
373 sType = OUString( "calc_MS_Excel_97" );
374 else
375 if ( sModule == "com.sun.star.drawing.DrawingDocument" )
376 sType = OUString( "impress_MS_PowerPoint_97" );
377 else
378 if ( sModule == "com.sun.star.presentation.PresentationDocument" )
379 sType = OUString( "impress_MS_PowerPoint_97" );
381 break;
383 case E_OOO_DOC:
385 if ( sModule == "com.sun.star.text.TextDocument" )
386 sType = OUString( "writer8" );
387 else
388 if ( sModule == "com.sun.star.sheet.SpreadsheetDocument" )
389 sType = OUString( "calc8" );
390 else
391 if ( sModule == "com.sun.star.drawing.DrawingDocument" )
392 sType = OUString( "draw8" );
393 else
394 if ( sModule == "com.sun.star.presentation.PresentationDocument" )
395 sType = OUString( "impress8" );
397 break;
400 return sType;
402 catch (const css::uno::RuntimeException&)
404 throw;
406 catch (const css::uno::Exception&)
410 return OUString();
413 //--------------------------------------------------------------------
415 SAL_DLLPRIVATE void SfxViewShell::IPClientGone_Impl( SfxInPlaceClient *pIPClient )
417 SfxInPlaceClientList* pClientList = GetIPClientList_Impl(sal_True);
419 for( SfxInPlaceClientList::iterator it = pClientList->begin(); it != pClientList->end(); ++it )
421 if ( *it == pIPClient )
423 pClientList->erase( it );
424 break;
431 //--------------------------------------------------------------------
433 void SfxViewShell::ExecMisc_Impl( SfxRequest &rReq )
435 const sal_uInt16 nId = rReq.GetSlot();
436 switch( nId )
438 case SID_STYLE_FAMILY :
440 SFX_REQUEST_ARG(rReq, pItem, SfxUInt16Item, nId, sal_False);
441 if (pItem)
443 pImp->m_nFamily = pItem->GetValue();
445 break;
447 case SID_ACTIVATE_STYLE_APPLY:
449 uno::Reference< frame::XFrame > xFrame(
450 GetViewFrame()->GetFrame().GetFrameInterface(),
451 uno::UNO_QUERY);
453 Reference< beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
454 Reference< frame::XLayoutManager > xLayoutManager;
455 if ( xPropSet.is() )
459 Any aValue = xPropSet->getPropertyValue( OUString( "LayoutManager" ));
460 aValue >>= xLayoutManager;
461 if ( xLayoutManager.is() )
463 OUString aTextResString( "private:resource/toolbar/textobjectbar" );
464 uno::Reference< ui::XUIElement > xElement = xLayoutManager->getElement( aTextResString );
465 if(!xElement.is())
467 OUString aFrameResString( "private:resource/toolbar/frameobjectbar" );
468 xElement = xLayoutManager->getElement( aFrameResString );
470 if(!xElement.is())
472 OUString aOleResString( "private:resource/toolbar/oleobjectbar" );
473 xElement = xLayoutManager->getElement( aOleResString );
475 if(xElement.is())
477 uno::Reference< awt::XWindow > xWin( xElement->getRealInterface(), uno::UNO_QUERY_THROW );
478 Window* pWin = VCLUnoHelper::GetWindow( xWin );
479 ToolBox* pTextToolbox = dynamic_cast< ToolBox* >( pWin );
480 if( pTextToolbox )
482 sal_uInt16 nItemCount = pTextToolbox->GetItemCount();
483 for( sal_uInt16 nItem = 0; nItem < nItemCount; ++nItem )
485 sal_uInt16 nItemId = pTextToolbox->GetItemId( nItem );
486 const OUString& rCommand = pTextToolbox->GetItemCommand( nItemId );
487 if (rCommand == ".uno:StyleApply")
489 Window* pItemWin = pTextToolbox->GetItemWindow( nItemId );
490 if( pItemWin )
491 pItemWin->GrabFocus();
492 break;
499 catch (const Exception&)
503 rReq.Done();
505 break;
506 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
508 case SID_MAIL_SENDDOCASMS:
509 case SID_MAIL_SENDDOCASOOO:
510 case SID_MAIL_SENDDOCASPDF:
511 case SID_MAIL_SENDDOC:
512 case SID_MAIL_SENDDOCASFORMAT:
514 SfxObjectShell* pDoc = GetObjectShell();
515 if ( pDoc && pDoc->QueryHiddenInformation(
516 WhenSaving, &GetViewFrame()->GetWindow() ) != RET_YES )
517 break;
520 SfxMailModel aModel;
521 OUString aDocType;
523 SFX_REQUEST_ARG(rReq, pMailSubject, SfxStringItem, SID_MAIL_SUBJECT, sal_False );
524 if ( pMailSubject )
525 aModel.SetSubject( pMailSubject->GetValue() );
527 SFX_REQUEST_ARG(rReq, pMailRecipient, SfxStringItem, SID_MAIL_RECIPIENT, sal_False );
528 if ( pMailRecipient )
530 String aRecipient( pMailRecipient->GetValue() );
531 String aMailToStr(OUString("mailto:"));
533 if ( aRecipient.Search( aMailToStr ) == 0 )
534 aRecipient = aRecipient.Erase( 0, aMailToStr.Len() );
535 aModel.AddAddress( aRecipient, SfxMailModel::ROLE_TO );
537 SFX_REQUEST_ARG(rReq, pMailDocType, SfxStringItem, SID_TYPE_NAME, sal_False );
538 if ( pMailDocType )
539 aDocType = pMailDocType->GetValue();
541 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
542 SfxMailModel::SendMailResult eResult = SfxMailModel::SEND_MAIL_ERROR;
544 if ( nId == SID_MAIL_SENDDOC )
545 eResult = aModel.SaveAndSend( xFrame, OUString() );
546 else if ( nId == SID_MAIL_SENDDOCASPDF )
547 eResult = aModel.SaveAndSend( xFrame, OUString( "pdf_Portable_Document_Format" ));
548 else if ( nId == SID_MAIL_SENDDOCASMS )
550 aDocType = impl_searchFormatTypeForApp(xFrame, E_MS_DOC);
551 if (!aDocType.isEmpty())
552 eResult = aModel.SaveAndSend( xFrame, aDocType );
554 else if ( nId == SID_MAIL_SENDDOCASOOO )
556 aDocType = impl_searchFormatTypeForApp(xFrame, E_OOO_DOC);
557 if (!aDocType.isEmpty())
558 eResult = aModel.SaveAndSend( xFrame, aDocType );
561 if ( eResult == SfxMailModel::SEND_MAIL_ERROR )
563 InfoBox aBox( SFX_APP()->GetTopWindow(), SfxResId( MSG_ERROR_SEND_MAIL ));
564 aBox.Execute();
565 rReq.Ignore();
567 else
568 rReq.Done();
570 break;
572 case SID_BLUETOOTH_SENDDOC:
574 SfxBluetoothModel aModel;
575 SfxObjectShell* pDoc = GetObjectShell();
576 if ( pDoc && pDoc->QueryHiddenInformation(
577 WhenSaving, &GetViewFrame()->GetWindow() ) != RET_YES )
578 break;
579 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
580 SfxMailModel::SendMailResult eResult = aModel.SaveAndSend( xFrame, OUString() );
581 if( eResult == SfxMailModel::SEND_MAIL_ERROR )
583 InfoBox aBox( SFX_APP()->GetTopWindow(), SfxResId( MSG_ERROR_SEND_MAIL ));
584 aBox.Execute();
585 rReq.Ignore();
587 else
588 rReq.Done();
590 break;
592 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
593 case SID_WEBHTML:
595 static const char HTML_DOCUMENT_TYPE[] = "generic_HTML";
596 static const char HTML_GRAPHIC_TYPE[] = "graphic_HTML";
597 const sal_Int32 FILTERFLAG_EXPORT = 0x00000002;
599 css::uno::Reference< lang::XMultiServiceFactory > xSMGR(::comphelper::getProcessServiceFactory(), css::uno::UNO_QUERY_THROW);
600 css::uno::Reference< uno::XComponentContext > xContext(::comphelper::getProcessComponentContext(), css::uno::UNO_QUERY_THROW);
601 css::uno::Reference< css::frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
602 css::uno::Reference< css::frame::XModel > xModel;
604 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager( css::frame::ModuleManager::create(xContext) );
606 OUString aModule;
609 aModule = xModuleManager->identify( xFrame );
611 catch (const css::uno::RuntimeException&)
613 throw;
615 catch (const css::uno::Exception&)
619 if ( xFrame.is() )
621 css::uno::Reference< css::frame::XController > xController = xFrame->getController();
622 if ( xController.is() )
623 xModel = xController->getModel();
626 // We need at least a valid module name and model reference
627 css::uno::Reference< css::frame::XStorable > xStorable( xModel, css::uno::UNO_QUERY );
628 if ( xModel.is() && xStorable.is() )
630 OUString aFilterName;
631 OUString aTypeName( HTML_DOCUMENT_TYPE );
632 OUString aFileName;
633 OUString aExtension( "htm" );
635 OUString aLocation = xStorable->getLocation();
636 INetURLObject aFileObj( aLocation );
638 bool bPrivateProtocol = ( aFileObj.GetProtocol() == INET_PROT_PRIV_SOFFICE );
639 bool bHasLocation = !aLocation.isEmpty() && !bPrivateProtocol;
641 css::uno::Reference< css::container::XContainerQuery > xContainerQuery(
642 xSMGR->createInstance( OUString(
643 "com.sun.star.document.FilterFactory" )),
644 css::uno::UNO_QUERY_THROW );
646 // Retrieve filter from type
647 sal_Int32 nFilterFlags = FILTERFLAG_EXPORT;
648 aFilterName = impl_retrieveFilterNameFromTypeAndModule( xContainerQuery, aTypeName, aModule, nFilterFlags );
649 if ( aFilterName.isEmpty() )
651 // Draw/Impress uses a different type. 2nd chance try to use alternative type name
652 aFilterName = impl_retrieveFilterNameFromTypeAndModule(
653 xContainerQuery, OUString( HTML_GRAPHIC_TYPE ), aModule, nFilterFlags );
656 // No filter found => error
657 // No type and no location => error
658 if ( aFilterName.isEmpty() || aTypeName.isEmpty())
660 rReq.Done(sal_False);
661 return;
664 // Use provided save file name. If empty determine file name
665 if ( !bHasLocation )
667 // Create a default file name with the correct extension
668 const OUString aPreviewFileName( "webpreview" );
669 aFileName = aPreviewFileName;
671 else
673 // Determine file name from model
674 INetURLObject aFObj( xStorable->getLocation() );
675 aFileName = aFObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::NO_DECODE );
678 OSL_ASSERT( !aFilterName.isEmpty() );
679 OSL_ASSERT( !aFileName.isEmpty() );
681 // Creates a temporary directory to store our predefined file into it.
682 ::utl::TempFile aTempDir( NULL, sal_True );
684 INetURLObject aFilePathObj( aTempDir.GetURL() );
685 aFilePathObj.insertName( aFileName );
686 aFilePathObj.setExtension( aExtension );
688 OUString aFileURL = aFilePathObj.GetMainURL( INetURLObject::NO_DECODE );
690 css::uno::Sequence< css::beans::PropertyValue > aArgs( 1 );
691 aArgs[0].Name = OUString( "FilterName" );
692 aArgs[0].Value = css::uno::makeAny( aFilterName );
694 // Store document in the html format
697 xStorable->storeToURL( aFileURL, aArgs );
699 catch (const io::IOException&)
701 rReq.Done(sal_False);
702 return;
705 rReq.Done(sfx2::openUriExternally(aFileURL, true));
706 break;
708 else
710 rReq.Done(sal_False);
711 return;
715 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
716 case SID_PLUGINS_ACTIVE:
718 SFX_REQUEST_ARG(rReq, pShowItem, SfxBoolItem, nId, sal_False);
719 bool const bActive = (pShowItem)
720 ? pShowItem->GetValue()
721 : !pImp->m_bPlugInsActive;
722 // ggf. recorden
723 if ( !rReq.IsAPI() )
724 rReq.AppendItem( SfxBoolItem( nId, bActive ) );
726 // Jetzt schon DONE aufrufen, da die Argumente evtl. einen Pool
727 // benutzen, der demn"achst weg ist
728 rReq.Done(sal_True);
730 // ausfuehren
731 if (!pShowItem || (bActive != pImp->m_bPlugInsActive))
733 SfxFrame* pTopFrame = &GetFrame()->GetTopFrame();
734 if ( pTopFrame != &GetFrame()->GetFrame() )
736 // FramesetDocument
737 SfxViewShell *pShell = pTopFrame->GetCurrentViewFrame()->GetViewShell();
738 if ( pShell->GetInterface()->GetSlot( nId ) )
739 pShell->ExecuteSlot( rReq );
740 break;
743 SfxFrameIterator aIter( *pTopFrame );
744 while ( pTopFrame )
746 if ( pTopFrame->GetCurrentViewFrame() )
748 SfxViewShell *pView = pTopFrame->GetCurrentViewFrame()->GetViewShell();
749 if ( pView )
751 pView->pImp->m_bPlugInsActive = bActive;
752 Rectangle aVisArea = GetObjectShell()->GetVisArea();
753 VisAreaChanged(aVisArea);
755 // the plugins might need change in their state
756 SfxInPlaceClientList *pClients = pView->GetIPClientList_Impl(sal_False);
757 if ( pClients )
759 for ( size_t n = 0; n < pClients->size(); n++)
761 SfxInPlaceClient* pIPClient = pClients->at( n );
762 if ( pIPClient )
763 pView->CheckIPClient_Impl( pIPClient, aVisArea );
769 if ( !pTopFrame->GetParentFrame() )
770 pTopFrame = aIter.FirstFrame();
771 else
772 pTopFrame = aIter.NextFrame( *pTopFrame );
776 break;
781 //--------------------------------------------------------------------
783 void SfxViewShell::GetState_Impl( SfxItemSet &rSet )
785 DBG_CHKTHIS(SfxViewShell, 0);
787 SfxWhichIter aIter( rSet );
788 for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() )
790 switch ( nSID )
792 // Printer functions
793 case SID_PRINTDOC:
794 case SID_PRINTDOCDIRECT:
795 case SID_SETUPPRINTER:
796 case SID_PRINTER_NAME:
798 bool bEnabled = pImp->m_bCanPrint && !pImp->m_nPrinterLocks;
799 bEnabled = bEnabled && !Application::GetSettings().GetMiscSettings().GetDisablePrinting();
800 if ( bEnabled )
802 SfxPrinter *pPrinter = GetPrinter(sal_False);
804 if ( SID_PRINTDOCDIRECT == nSID )
806 OUString aPrinterName;
807 if ( pPrinter != NULL )
808 aPrinterName = pPrinter->GetName();
809 else
810 aPrinterName = Printer::GetDefaultPrinterName();
811 if ( !aPrinterName.isEmpty() )
813 uno::Reference < frame::XFrame > xFrame( pFrame->GetFrame().GetFrameInterface() );
815 OUStringBuffer aBuffer( 60 );
816 aBuffer.append( RetrieveLabelFromCommand(
817 OUString( ".uno:PrintDefault" ),
818 xFrame ));
819 aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM(" ("));
820 aBuffer.append( aPrinterName );
821 aBuffer.append(')');
823 rSet.Put( SfxStringItem( SID_PRINTDOCDIRECT, aBuffer.makeStringAndClear() ) );
826 bEnabled = !pPrinter || !pPrinter->IsPrinting();
828 break;
831 // PlugIns running
832 case SID_PLUGINS_ACTIVE:
834 rSet.Put( SfxBoolItem( SID_PLUGINS_ACTIVE, !pImp->m_bPlugInsActive) );
835 break;
837 case SID_STYLE_FAMILY :
839 rSet.Put( SfxUInt16Item( SID_STYLE_FAMILY, pImp->m_nFamily ) );
840 break;
846 //--------------------------------------------------------------------
848 void SfxViewShell::SetZoomFactor( const Fraction &rZoomX,
849 const Fraction &rZoomY )
851 DBG_ASSERT( GetWindow(), "no window" );
852 MapMode aMap( GetWindow()->GetMapMode() );
853 aMap.SetScaleX( rZoomX );
854 aMap.SetScaleY( rZoomY );
855 GetWindow()->SetMapMode( aMap );
858 //--------------------------------------------------------------------
859 ErrCode SfxViewShell::DoVerb(long /*nVerb*/)
861 /* [Description]
863 Virtual Method used to perform a Verb on a selected Object.
864 Since this Object is just known by the derived classes, DoVerb
865 must be overloaded.
869 return ERRCODE_SO_NOVERBS;
872 //--------------------------------------------------------------------
874 void SfxViewShell::OutplaceActivated( sal_Bool bActive, SfxInPlaceClient* /*pClient*/ )
876 if ( !bActive )
877 GetFrame()->GetFrame().Appear();
880 //--------------------------------------------------------------------
882 void SfxViewShell::InplaceActivating( SfxInPlaceClient* /*pClient*/ )
884 // TODO/LATER: painting of the bitmap can be stopped, it is required if CLIPCHILDREN problem #i25788# is not solved,
885 // but may be the bug will not affect the real office vcl windows, then it is not required
888 //--------------------------------------------------------------------
890 void SfxViewShell::InplaceDeactivated( SfxInPlaceClient* /*pClient*/ )
892 // TODO/LATER: paint the replacement image in normal way if the painting was stopped
895 //--------------------------------------------------------------------
897 void SfxViewShell::UIActivating( SfxInPlaceClient* /*pClient*/ )
899 uno::Reference < frame::XFrame > xOwnFrame( pFrame->GetFrame().GetFrameInterface() );
900 uno::Reference < frame::XFramesSupplier > xParentFrame( xOwnFrame->getCreator(), uno::UNO_QUERY );
901 if ( xParentFrame.is() )
902 xParentFrame->setActiveFrame( xOwnFrame );
904 pFrame->GetBindings().HidePopups(sal_True);
905 pFrame->GetDispatcher()->Update_Impl( sal_True );
908 //--------------------------------------------------------------------
910 void SfxViewShell::UIDeactivated( SfxInPlaceClient* /*pClient*/ )
912 if ( !pFrame->GetFrame().IsClosing_Impl() || SfxViewFrame::Current() != pFrame )
913 pFrame->GetDispatcher()->Update_Impl( sal_True );
914 pFrame->GetBindings().HidePopups(sal_False);
916 pFrame->GetBindings().InvalidateAll(sal_True);
919 //--------------------------------------------------------------------
921 SfxInPlaceClient* SfxViewShell::FindIPClient
923 const uno::Reference < embed::XEmbeddedObject >& xObj,
924 Window* pObjParentWin
925 ) const
927 SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False);
928 if ( !pClients )
929 return 0;
931 if( !pObjParentWin )
932 pObjParentWin = GetWindow();
933 for ( size_t n = 0; n < pClients->size(); n++)
935 SfxInPlaceClient *pIPClient = (SfxInPlaceClient*) pClients->at( n );
936 if ( pIPClient->GetObject() == xObj && pIPClient->GetEditWin() == pObjParentWin )
937 return pIPClient;
940 return 0;
943 //--------------------------------------------------------------------
945 SfxInPlaceClient* SfxViewShell::GetIPClient() const
947 return GetUIActiveClient();
950 //--------------------------------------------------------------------
952 SfxInPlaceClient* SfxViewShell::GetUIActiveIPClient_Impl() const
954 // this method is needed as long as SFX still manages the border space for ChildWindows (see SfxFrame::Resize)
955 SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False);
956 if ( !pClients )
957 return 0;
959 for ( size_t n = 0; n < pClients->size(); n++)
961 SfxInPlaceClient* pIPClient = pClients->at( n );
962 if ( pIPClient->IsUIActive() )
963 return pIPClient;
966 return NULL;
969 SfxInPlaceClient* SfxViewShell::GetUIActiveClient() const
971 SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False);
972 if ( !pClients )
973 return 0;
975 for ( size_t n = 0; n < pClients->size(); n++)
977 SfxInPlaceClient* pIPClient = pClients->at( n );
978 if ( pIPClient->IsObjectUIActive() )
979 return pIPClient;
982 return NULL;
985 //--------------------------------------------------------------------
987 void SfxViewShell::Activate( sal_Bool bMDI )
989 DBG_CHKTHIS(SfxViewShell, 0);
990 if ( bMDI )
992 SfxObjectShell *pSh = GetViewFrame()->GetObjectShell();
993 if ( pSh->GetModel().is() )
994 pSh->GetModel()->setCurrentController( GetViewFrame()->GetFrame().GetController() );
996 SetCurrentDocument();
1000 //--------------------------------------------------------------------
1002 void SfxViewShell::Deactivate(sal_Bool /*bMDI*/)
1004 DBG_CHKTHIS(SfxViewShell, 0);
1007 //--------------------------------------------------------------------
1009 void SfxViewShell::AdjustPosSizePixel
1011 const Point& /*rToolOffset*/,// Upper left corner Tools in Frame-Window
1012 const Size& /*rSize*/ // All available sizes.
1016 DBG_CHKTHIS(SfxViewShell, 0);
1019 //--------------------------------------------------------------------
1021 void SfxViewShell::Move()
1023 /* [Description]
1025 This virtual Method is called when the window displayed in the
1026 SfxViewShell gets a StarView-Move() notification.
1028 This base implementation does not have to be called. .
1030 [Note]
1032 This Method can be used to cancel a selection, in order to catch the
1033 mouse movement which is due to moving a window.
1035 For now the notification does not work In-Place.
1041 //--------------------------------------------------------------------
1043 void SfxViewShell::OuterResizePixel
1045 const Point& /*rToolOffset*/,// Upper left corner Tools in Frame-Window
1046 const Size& /*rSize*/ // All available sizes.
1049 /* [Description]
1051 This Method has to be overloaded to be able to react to the size-change of
1052 the View. Thus the View is defined as the Edit window and also the
1053 attached Tools are defined (for example the ruler).
1055 The Edit window must not be changed either in size or position.
1057 The Vis-Area of SfxObjectShell, its scale and position can be changed
1058 here. The mainuse is to change the size of the Vis-Area.
1060 If the Border is changed due to the new calculation then this has to be set
1061 by <SfxViewShell::SetBorderPixel(const SvBorder&)>. The Postioning of Tools
1062 is only allowed after the calling of 'SetBorderPixel'.
1064 [Example]
1066 void AppViewSh::OuterViewResizePixel( const Point &rOfs, const Size &rSz )
1068 // Calculate Tool position and size externally, do not set!
1069 // (due to the following Border calculation)
1070 Point aHLinPos...; Size aHLinSz...;
1073 // Calculate and Set a Border of Tools which matches rSize.
1074 SvBorder aBorder...
1075 SetBorderPixel( aBorder ); // Allow Positioning from here on.
1077 // Arrange Tools
1078 pHLin->SetPosSizePixel( aHLinPos, aHLinSz );
1082 [Cross-reference]
1084 <SfxViewShell::InnerResizePixel(const Point&,const Size& rSize)>
1088 DBG_CHKTHIS(SfxViewShell, 0);
1089 SetBorderPixel( SvBorder() );
1092 //--------------------------------------------------------------------
1094 void SfxViewShell::InnerResizePixel
1096 const Point& /*rToolOffset*/,// Upper left corner Tools in Frame-Window
1097 const Size& /*rSize*/ // All available sizes.
1100 /* [Description]
1102 This Method has to be overloaded to be able to react to the size-change of
1103 the Edit window.
1105 The Edit window must not be changed either in size or position.
1106 Neither the Vis-Area of SfxObjectShell nor its scale or position are
1107 allowed to be changed
1109 If the Border is changed due to the new calculation then is has to be set
1110 by <SfxViewShell::SetBorderPixel(const SvBorder&)>.
1111 The Postioning of Tools is only allowed after the calling of
1112 'SetBorderPixel'.
1115 [Note]
1117 void AppViewSh::InnerViewResizePixel( const Point &rOfs, const Size &rSz )
1119 // Calculate Tool position and size internally, do not set!
1120 // (due to the following Border calculation)
1121 Point aHLinPos...; Size aHLinSz...;
1124 // Calculate and Set a Border of Tools which matches rSize.
1125 SvBorder aBorder...
1126 SetBorderPixel( aBorder ); // Allow Positioning from here on.
1128 // Arrange Tools
1129 pHLin->SetPosSizePixel( aHLinPos, aHLinSz );
1133 [Cross-reference]
1135 <SfxViewShell::OuterResizePixel(const Point&,const Size& rSize)>
1139 DBG_CHKTHIS(SfxViewShell, 0);
1140 SetBorderPixel( SvBorder() );
1143 //--------------------------------------------------------------------
1145 void SfxViewShell::InvalidateBorder()
1147 DBG_CHKTHIS(SfxViewShell, 0);
1148 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" );
1150 GetViewFrame()->InvalidateBorderImpl( this );
1151 if (pImp->m_pController.is())
1153 pImp->m_pController->BorderWidthsChanged_Impl();
1157 //--------------------------------------------------------------------
1159 void SfxViewShell::SetBorderPixel( const SvBorder &rBorder )
1161 DBG_CHKTHIS(SfxViewShell, 0);
1162 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" );
1164 GetViewFrame()->SetBorderPixelImpl( this, rBorder );
1166 // notify related controller that border size is changed
1167 if (pImp->m_pController.is())
1169 pImp->m_pController->BorderWidthsChanged_Impl();
1173 //--------------------------------------------------------------------
1175 const SvBorder& SfxViewShell::GetBorderPixel() const
1177 DBG_CHKTHIS(SfxViewShell, 0);
1178 DBG_ASSERT( GetViewFrame(), "SfxViewShell without SfxViewFrame" );
1180 return GetViewFrame()->GetBorderPixelImpl( this );
1183 //--------------------------------------------------------------------
1185 void SfxViewShell::SetWindow
1187 Window* pViewPort // For example Null pointer in the Destructor.
1190 /* [Description]
1192 With this method the SfxViewShell is set in the data window. This is
1193 needed for the in-place container and for restoring the proper focus.
1195 Even in-place-active the conversion of the ViewPort Windows is forbidden.
1199 if( pWindow == pViewPort )
1200 return;
1202 // Disconnect existing IP-Clients if possible
1203 DisconnectAllClients();
1205 //TODO: should we have a "ReconnectAllClients" method?
1206 DiscardClients_Impl();
1208 // Switch View-Port
1209 sal_Bool bHadFocus = pWindow ? pWindow->HasChildPathFocus( sal_True ) : sal_False;
1210 pWindow = pViewPort;
1212 if( pWindow )
1214 // Disable automatic GUI mirroring (right-to-left) for document windows
1215 pWindow->EnableRTL( sal_False );
1218 if ( bHadFocus && pWindow )
1219 pWindow->GrabFocus();
1220 //TODO/CLEANUP
1221 //Do we still need this Method?!
1222 //SFX_APP()->GrabFocus( pWindow );
1225 //--------------------------------------------------------------------
1227 SfxViewShell::SfxViewShell
1229 SfxViewFrame* pViewFrame, /* <SfxViewFrame>, which will be
1230 displayed in this View */
1231 sal_uInt16 nFlags /* See <SfxViewShell-Flags> */
1234 : SfxShell(this)
1235 , pImp( new SfxViewShell_Impl(nFlags) )
1236 , pIPClientList( 0 )
1237 , pFrame(pViewFrame)
1238 , pSubShell(0)
1239 , pWindow(0)
1240 , bNoNewWindow( 0 != (nFlags & SFX_VIEW_NO_NEWWINDOW) )
1242 DBG_CTOR(SfxViewShell, 0);
1244 if ( pViewFrame->GetParentViewFrame() )
1246 pImp->m_bPlugInsActive = pViewFrame->GetParentViewFrame()
1247 ->GetViewShell()->pImp->m_bPlugInsActive;
1249 SetMargin( pViewFrame->GetMargin_Impl() );
1251 SetPool( &pViewFrame->GetObjectShell()->GetPool() );
1252 StartListening(*pViewFrame->GetObjectShell());
1254 // Insert into list
1255 SfxViewShellArr_Impl &rViewArr = SFX_APP()->GetViewShells_Impl();
1256 rViewArr.push_back(this);
1259 //--------------------------------------------------------------------
1261 SfxViewShell::~SfxViewShell()
1263 DBG_DTOR(SfxViewShell, 0);
1265 // Remove from list
1266 const SfxViewShell *pThis = this;
1267 SfxViewShellArr_Impl &rViewArr = SFX_APP()->GetViewShells_Impl();
1268 SfxViewShellArr_Impl::iterator it = std::find( rViewArr.begin(), rViewArr.end(), pThis );
1269 rViewArr.erase( it );
1271 if ( pImp->xClipboardListener.is() )
1273 pImp->xClipboardListener->DisconnectViewShell();
1274 pImp->xClipboardListener = NULL;
1277 if (pImp->m_pController.is())
1279 pImp->m_pController->ReleaseShell_Impl();
1280 pImp->m_pController.clear();
1283 DELETEZ( pImp );
1284 DELETEZ( pIPClientList );
1287 //--------------------------------------------------------------------
1289 sal_uInt16 SfxViewShell::PrepareClose
1291 sal_Bool bUI, // TRUE: Allow Dialog and so on, FALSE: silent-mode
1292 sal_Bool /*bForBrowsing*/
1295 SfxPrinter *pPrinter = GetPrinter();
1296 if ( pPrinter && pPrinter->IsPrinting() )
1298 if ( bUI )
1300 InfoBox aInfoBox( &GetViewFrame()->GetWindow(), SfxResId( MSG_CANT_CLOSE ) );
1301 aInfoBox.Execute();
1304 return sal_False;
1307 if( GetViewFrame()->IsInModalMode() )
1308 return sal_False;
1310 if( bUI && GetViewFrame()->GetDispatcher()->IsLocked() )
1311 return sal_False;
1313 return sal_True;
1316 //--------------------------------------------------------------------
1318 SfxViewShell* SfxViewShell::Current()
1320 SfxViewFrame *pCurrent = SfxViewFrame::Current();
1321 return pCurrent ? pCurrent->GetViewShell() : NULL;
1324 //--------------------------------------------------------------------
1326 SfxViewShell* SfxViewShell::Get( const Reference< XController>& i_rController )
1328 if ( !i_rController.is() )
1329 return NULL;
1331 for ( SfxViewShell* pViewShell = SfxViewShell::GetFirst( NULL, sal_False );
1332 pViewShell;
1333 pViewShell = SfxViewShell::GetNext( *pViewShell, NULL, sal_False )
1336 if ( pViewShell->GetController() == i_rController )
1337 return pViewShell;
1339 return NULL;
1342 //--------------------------------------------------------------------
1344 SdrView* SfxViewShell::GetDrawView() const
1346 /* [Description]
1348 This virtual Method has to be overloded by the sub classes, to be able
1349 make the Property-Editor available.
1351 The default implementation does always return zero.
1355 return 0;
1358 //--------------------------------------------------------------------
1360 String SfxViewShell::GetSelectionText
1362 sal_Bool /*bCompleteWords*/ /* FALSE (default)
1363 Only the actual selected text is returned.
1365 TRUE
1366 The selected text is expanded so that only
1367 whole words are returned. As word separators
1368 these are used: white spaces and punctuation
1369 ".,;" and single and double quotes.
1373 /* [Description]
1375 This Method can be overloaded by the programmers to return a text that
1376 is included in the current selection. This is for example used when
1377 sending emails.
1379 When called with "CompleteWords == TRUE", it is for example sufficent
1380 with having the Cursor positioned somewhere within an URL in-order
1381 to have the entire URL returned.
1385 return String();
1388 //--------------------------------------------------------------------
1390 sal_Bool SfxViewShell::HasSelection( sal_Bool ) const
1392 /* [Description]
1394 With this virtual Method can a for example a Dialog be queried, to
1395 check if something is selected in the current view. If the Parameter
1396 is <BOOL> TRUE then it is checked whether some text is selected.
1400 return sal_False;
1403 void SfxViewShell::AddSubShell( SfxShell& rShell )
1405 pImp->aArr.push_back(&rShell);
1406 SfxDispatcher *pDisp = pFrame->GetDispatcher();
1407 if ( pDisp->IsActive(*this) )
1409 pDisp->Push(rShell);
1410 pDisp->Flush();
1414 void SfxViewShell::RemoveSubShell( SfxShell* pShell )
1416 SfxDispatcher *pDisp = pFrame->GetDispatcher();
1417 if ( !pShell )
1419 size_t nCount = pImp->aArr.size();
1420 if ( pDisp->IsActive(*this) )
1422 for(size_t n = nCount; n > 0; --n)
1423 pDisp->Pop(*pImp->aArr[n - 1]);
1424 pDisp->Flush();
1426 pImp->aArr.clear();
1428 else
1430 SfxShellArr_Impl::iterator i = std::find(pImp->aArr.begin(), pImp->aArr.end(), pShell);
1431 if(i != pImp->aArr.end())
1433 pImp->aArr.erase(i);
1434 if(pDisp->IsActive(*this))
1436 pDisp->RemoveShell_Impl(*pShell);
1437 pDisp->Flush();
1443 SfxShell* SfxViewShell::GetSubShell( sal_uInt16 nNo )
1445 sal_uInt16 nCount = pImp->aArr.size();
1446 if(nNo < nCount)
1447 return pImp->aArr[nCount - nNo - 1];
1448 return NULL;
1451 void SfxViewShell::PushSubShells_Impl( sal_Bool bPush )
1453 SfxDispatcher *pDisp = pFrame->GetDispatcher();
1454 if ( bPush )
1456 for(SfxShellArr_Impl::const_iterator i = pImp->aArr.begin(); i != pImp->aArr.end(); ++i)
1457 pDisp->Push(**i);
1459 else if(!pImp->aArr.empty())
1461 SfxShell& rPopUntil = *pImp->aArr[0];
1462 if ( pDisp->GetShellLevel( rPopUntil ) != USHRT_MAX )
1463 pDisp->Pop( rPopUntil, SFX_SHELL_POP_UNTIL );
1466 pDisp->Flush();
1469 //--------------------------------------------------------------------
1471 void SfxViewShell::WriteUserData( String&, sal_Bool )
1475 //--------------------------------------------------------------------
1477 void SfxViewShell::ReadUserData(const String&, sal_Bool )
1481 void SfxViewShell::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue >&, sal_Bool )
1485 void SfxViewShell::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >&, sal_Bool )
1490 //--------------------------------------------------------------------
1491 // returns the first shell of spec. type viewing the specified doc.
1493 SfxViewShell* SfxViewShell::GetFirst
1495 const TypeId* pType,
1496 sal_Bool bOnlyVisible
1499 // search for a SfxViewShell of the specified type
1500 SfxViewShellArr_Impl &rShells = SFX_APP()->GetViewShells_Impl();
1501 SfxViewFrameArr_Impl &rFrames = SFX_APP()->GetViewFrames_Impl();
1502 for ( sal_uInt16 nPos = 0; nPos < rShells.size(); ++nPos )
1504 SfxViewShell *pShell = rShells[nPos];
1505 if ( pShell )
1507 // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame
1508 // these ViewShells shouldn't be accessible anymore
1509 // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps
1510 for ( sal_uInt16 n=0; n<rFrames.size(); ++n )
1512 SfxViewFrame *pFrame = rFrames[n];
1513 if ( pFrame == pShell->GetViewFrame() )
1515 // only ViewShells with a valid ViewFrame will be returned
1516 if ( ( !bOnlyVisible || pFrame->IsVisible() ) && ( !pType || pShell->IsA(*pType) ) )
1517 return pShell;
1518 break;
1524 return 0;
1527 //--------------------------------------------------------------------
1528 // returns the next shell of spec. type viewing the specified doc.
1530 SfxViewShell* SfxViewShell::GetNext
1532 const SfxViewShell& rPrev,
1533 const TypeId* pType,
1534 sal_Bool bOnlyVisible
1537 SfxViewShellArr_Impl &rShells = SFX_APP()->GetViewShells_Impl();
1538 SfxViewFrameArr_Impl &rFrames = SFX_APP()->GetViewFrames_Impl();
1539 sal_uInt16 nPos;
1540 for ( nPos = 0; nPos < rShells.size(); ++nPos )
1541 if ( rShells[nPos] == &rPrev )
1542 break;
1544 for ( ++nPos; nPos < rShells.size(); ++nPos )
1546 SfxViewShell *pShell = rShells[nPos];
1547 if ( pShell )
1549 // sometimes dangling SfxViewShells exist that point to a dead SfxViewFrame
1550 // these ViewShells shouldn't be accessible anymore
1551 // a destroyed ViewFrame is not in the ViewFrame array anymore, so checking this array helps
1552 for ( sal_uInt16 n=0; n<rFrames.size(); ++n )
1554 SfxViewFrame *pFrame = rFrames[n];
1555 if ( pFrame == pShell->GetViewFrame() )
1557 // only ViewShells with a valid ViewFrame will be returned
1558 if ( ( !bOnlyVisible || pFrame->IsVisible() ) && ( !pType || pShell->IsA(*pType) ) )
1559 return pShell;
1560 break;
1566 return 0;
1569 //--------------------------------------------------------------------
1571 void SfxViewShell::Notify( SfxBroadcaster& rBC,
1572 const SfxHint& rHint )
1574 if ( rHint.IsA(TYPE(SfxEventHint)) )
1576 switch ( ((SfxEventHint&)rHint).GetEventId() )
1578 case SFX_EVENT_LOADFINISHED:
1580 if ( GetController().is() )
1582 // avoid access to dangling ViewShells
1583 SfxViewFrameArr_Impl &rFrames = SFX_APP()->GetViewFrames_Impl();
1584 for ( sal_uInt16 n=0; n<rFrames.size(); ++n )
1586 SfxViewFrame *frame = rFrames[n];
1587 if ( frame == GetViewFrame() && &rBC == GetObjectShell() )
1589 SfxItemSet* pSet = GetObjectShell()->GetMedium()->GetItemSet();
1590 SFX_ITEMSET_ARG( pSet, pItem, SfxUnoAnyItem, SID_VIEW_DATA, sal_False );
1591 if ( pItem )
1593 pImp->m_pController->restoreViewData( pItem->GetValue() );
1594 pSet->ClearItem( SID_VIEW_DATA );
1597 break;
1602 break;
1608 //--------------------------------------------------------------------
1610 sal_Bool SfxViewShell::ExecKey_Impl(const KeyEvent& aKey)
1612 if (!pImp->m_pAccExec.get())
1614 pImp->m_pAccExec.reset(
1615 ::svt::AcceleratorExecute::createAcceleratorHelper() );
1616 pImp->m_pAccExec->init(::comphelper::getProcessComponentContext(),
1617 pFrame->GetFrame().GetFrameInterface());
1620 return pImp->m_pAccExec->execute(aKey.GetKeyCode());
1623 //--------------------------------------------------------------------
1625 bool SfxViewShell::KeyInput( const KeyEvent &rKeyEvent )
1627 /* [Description]
1629 This Method executes the KeyEvent 'rKeyEvent' of the Keys (Accelerator)
1630 configured either direct or indirect (for example by the Application)
1631 in the SfxViewShell.
1633 [Return value]
1635 bool TRUE
1636 The Key (Accelerator) is configured and the
1637 the associated Handler was called
1639 FALSE
1640 The Key (Accelerator) is not configured and
1641 subsequently no Handler was called
1643 [Cross-reference]
1645 <SfxApplication::KeyInput(const KeyEvent&)>
1648 return ExecKey_Impl(rKeyEvent);
1651 bool SfxViewShell::GlobalKeyInput_Impl( const KeyEvent &rKeyEvent )
1653 return ExecKey_Impl(rKeyEvent);
1656 //--------------------------------------------------------------------
1658 void SfxViewShell::ShowCursor( bool /*bOn*/ )
1660 /* [Description]
1662 This Method has to be overloaded by the subclasses so that SFx from
1663 the Cursor can be switched on and off. This happes for example with
1664 with the running <SfxProgress>.
1670 //--------------------------------------------------------------------
1672 void SfxViewShell::GotFocus() const
1674 /* [Description]
1676 This Method has to be called by the programmer, when the
1677 Edit window has received the focus. This gives for example the SFx
1678 the power to turn on the accelerator.
1680 [Note]
1682 <StarView> does sadly enough not provide the possibillity to attach
1683 such "side-way" events.
1689 //--------------------------------------------------------------------
1690 void SfxViewShell::ResetAllClients_Impl( SfxInPlaceClient *pIP )
1693 SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False);
1694 if ( !pClients )
1695 return;
1697 for ( size_t n = 0; n < pClients->size(); n++ )
1699 SfxInPlaceClient* pIPClient = pClients->at( n );
1700 if( pIPClient != pIP )
1701 pIPClient->ResetObject();
1705 //--------------------------------------------------------------------
1707 void SfxViewShell::DisconnectAllClients()
1709 SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False);
1710 if ( !pClients )
1711 return;
1713 for ( size_t n = 0; n < pClients->size(); )
1714 // clients will remove themselves from the list
1715 delete pClients->at( n );
1718 //--------------------------------------------------------------------
1720 void SfxViewShell::QueryObjAreaPixel( Rectangle& ) const
1724 //--------------------------------------------------------------------
1726 void SfxViewShell::VisAreaChanged(const Rectangle& /*rVisArea*/)
1728 SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False);
1729 if ( !pClients )
1730 return;
1732 for ( size_t n = 0; n < pClients->size(); n++)
1734 SfxInPlaceClient* pIPClient = pClients->at( n );
1735 if ( pIPClient->IsObjectInPlaceActive() )
1736 // client is active, notify client that the VisArea might have changed
1737 pIPClient->VisAreaChanged();
1741 //--------------------------------------------------------------------
1742 void SfxViewShell::CheckIPClient_Impl( SfxInPlaceClient *pIPClient, const Rectangle& rVisArea )
1744 if ( GetObjectShell()->IsInClose() )
1745 return;
1747 sal_Bool bAlwaysActive =
1748 ( ( pIPClient->GetObjectMiscStatus() & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY ) != 0 );
1749 sal_Bool bActiveWhenVisible =
1750 ( ( pIPClient->GetObjectMiscStatus() & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE ) != 0 );
1752 // this method is called when either a client is created or the "Edit/Plugins" checkbox is checked
1753 if ( !pIPClient->IsObjectInPlaceActive() && pImp->m_bPlugInsActive )
1755 // object in client is currently not active
1756 // check if the object wants to be activated always or when it becomes at least partially visible
1757 // TODO/LATER: maybe we should use the scaled area instead of the ObjArea?!
1758 if ( bAlwaysActive || (bActiveWhenVisible && rVisArea.IsOver(pIPClient->GetObjArea())) )
1762 pIPClient->GetObject()->changeState( embed::EmbedStates::INPLACE_ACTIVE );
1764 catch (const uno::Exception&)
1769 else if (!pImp->m_bPlugInsActive)
1771 // object in client is currently active and "Edit/Plugins" checkbox is selected
1772 // check if the object wants to be activated always or when it becomes at least partially visible
1773 // in this case selecting of the "Edit/Plugin" checkbox should let such objects deactivate
1774 if ( bAlwaysActive || bActiveWhenVisible )
1775 pIPClient->GetObject()->changeState( embed::EmbedStates::RUNNING );
1779 //--------------------------------------------------------------------
1780 void SfxViewShell::DiscardClients_Impl()
1782 /* [Description]
1784 The purpose of this Method is to prevent the saving of Objects when closing
1785 the Document, if the user has chosen to close without saving.
1789 SfxInPlaceClientList *pClients = GetIPClientList_Impl(sal_False);
1790 if ( !pClients )
1791 return;
1793 for ( size_t n = 0; n < pClients->size(); )
1794 delete pClients->at( n );
1797 //--------------------------------------------------------------------
1799 SfxObjectShell* SfxViewShell::GetObjectShell()
1801 return pFrame ? pFrame->GetObjectShell() : NULL;
1804 //--------------------------------------------------------------------
1806 Reference< XModel > SfxViewShell::GetCurrentDocument() const
1808 Reference< XModel > xDocument;
1810 const SfxObjectShell* pDocShell( const_cast< SfxViewShell* >( this )->GetObjectShell() );
1811 OSL_ENSURE( pDocShell, "SfxViewFrame::GetCurrentDocument: no DocShell!?" );
1812 if ( pDocShell )
1813 xDocument = pDocShell->GetModel();
1814 return xDocument;
1817 //--------------------------------------------------------------------
1819 void SfxViewShell::SetCurrentDocument() const
1821 uno::Reference< frame::XModel > xDocument( GetCurrentDocument() );
1822 if ( xDocument.is() )
1823 SfxObjectShell::SetCurrentComponent( xDocument );
1826 //--------------------------------------------------------------------
1828 const Size& SfxViewShell::GetMargin() const
1830 return pImp->aMargin;
1833 //--------------------------------------------------------------------
1835 void SfxViewShell::SetMargin( const Size& rSize )
1837 // the default margin was verified using www.apple.com !!
1838 Size aMargin = rSize;
1839 if ( aMargin.Width() == -1 )
1840 aMargin.Width() = DEFAULT_MARGIN_WIDTH;
1841 if ( aMargin.Height() == -1 )
1842 aMargin.Height() = DEFAULT_MARGIN_HEIGHT;
1844 if ( aMargin != pImp->aMargin )
1846 pImp->aMargin = aMargin;
1847 MarginChanged();
1851 //--------------------------------------------------------------------
1853 void SfxViewShell::MarginChanged()
1857 //--------------------------------------------------------------------
1859 sal_Bool SfxViewShell::IsShowView_Impl() const
1861 return pImp->m_bIsShowView;
1864 //--------------------------------------------------------------------
1866 SfxFrame* SfxViewShell::GetSmartSelf( SfxFrame* pSelf, SfxMedium& /*rMedium*/ )
1868 return pSelf;
1871 //------------------------------------------------------------------------
1873 void SfxViewShell::JumpToMark( const String& rMark )
1875 SfxStringItem aMarkItem( SID_JUMPTOMARK, rMark );
1876 GetViewFrame()->GetDispatcher()->Execute(
1877 SID_JUMPTOMARK,
1878 SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD,
1879 &aMarkItem, 0L );
1882 //------------------------------------------------------------------------
1884 SfxInPlaceClientList* SfxViewShell::GetIPClientList_Impl( sal_Bool bCreate ) const
1886 if ( !pIPClientList && bCreate )
1887 ( (SfxViewShell*) this )->pIPClientList = new SfxInPlaceClientList;
1888 return pIPClientList;
1891 void SfxViewShell::SetController( SfxBaseController* pController )
1893 pImp->m_pController = pController;
1894 pImp->m_bControllerSet = true;
1896 // there should be no old listener, but if there is one, it should be disconnected
1897 if ( pImp->xClipboardListener.is() )
1898 pImp->xClipboardListener->DisconnectViewShell();
1900 pImp->xClipboardListener = new SfxClipboardChangeListener( this, GetClipboardNotifier() );
1903 Reference < XController > SfxViewShell::GetController()
1905 return pImp->m_pController.get();
1908 SfxBaseController* SfxViewShell::GetBaseController_Impl() const
1910 return pImp->m_pController.get();
1913 void SfxViewShell::AddContextMenuInterceptor_Impl( const uno::Reference< ui::XContextMenuInterceptor >& xInterceptor )
1915 pImp->aInterceptorContainer.addInterface( xInterceptor );
1918 void SfxViewShell::RemoveContextMenuInterceptor_Impl( const uno::Reference< ui::XContextMenuInterceptor >& xInterceptor )
1920 pImp->aInterceptorContainer.removeInterface( xInterceptor );
1923 void Change( Menu* pMenu, SfxViewShell* pView )
1925 SfxDispatcher *pDisp = pView->GetViewFrame()->GetDispatcher();
1926 sal_uInt16 nCount = pMenu->GetItemCount();
1927 for ( sal_uInt16 nPos=0; nPos<nCount; ++nPos )
1929 sal_uInt16 nId = pMenu->GetItemId(nPos);
1930 String aCmd = pMenu->GetItemCommand(nId);
1931 PopupMenu* pPopup = pMenu->GetPopupMenu(nId);
1932 if ( pPopup )
1934 Change( pPopup, pView );
1936 else if ( nId < 5000 )
1938 if ( aCmd.CompareToAscii(".uno:", 5) == 0 )
1940 for (sal_uInt16 nIdx=0;;)
1942 SfxShell *pShell=pDisp->GetShell(nIdx++);
1943 if (pShell == NULL)
1944 break;
1945 const SfxInterface *pIFace = pShell->GetInterface();
1946 const SfxSlot* pSlot = pIFace->GetSlot( aCmd );
1947 if ( pSlot )
1949 pMenu->InsertItem( pSlot->GetSlotId(), pMenu->GetItemText( nId ),
1950 pMenu->GetItemBits( nId ), OString(), nPos );
1951 pMenu->SetItemCommand( pSlot->GetSlotId(), aCmd );
1952 pMenu->RemoveItem( nPos+1 );
1953 break;
1962 sal_Bool SfxViewShell::TryContextMenuInterception( Menu& rIn, const OUString& rMenuIdentifier, Menu*& rpOut, ui::ContextMenuExecuteEvent aEvent )
1964 rpOut = NULL;
1965 sal_Bool bModified = sal_False;
1967 // create container from menu
1968 aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
1969 &rIn, &rMenuIdentifier );
1971 // get selection from controller
1972 aEvent.Selection = uno::Reference < view::XSelectionSupplier > ( GetController(), uno::UNO_QUERY );
1974 // call interceptors
1975 ::cppu::OInterfaceIteratorHelper aIt( pImp->aInterceptorContainer );
1976 while( aIt.hasMoreElements() )
1980 ui::ContextMenuInterceptorAction eAction =
1981 ((ui::XContextMenuInterceptor*)aIt.next())->notifyContextMenuExecute( aEvent );
1982 switch ( eAction )
1984 case ui::ContextMenuInterceptorAction_CANCELLED :
1985 // interceptor does not want execution
1986 return sal_False;
1987 case ui::ContextMenuInterceptorAction_EXECUTE_MODIFIED :
1988 // interceptor wants his modified menu to be executed
1989 bModified = sal_True;
1990 break;
1991 case ui::ContextMenuInterceptorAction_CONTINUE_MODIFIED :
1992 // interceptor has modified menu, but allows for calling other interceptors
1993 bModified = sal_True;
1994 continue;
1995 case ui::ContextMenuInterceptorAction_IGNORED :
1996 // interceptor is indifferent
1997 continue;
1998 default:
1999 OSL_FAIL("Wrong return value of ContextMenuInterceptor!");
2000 continue;
2003 catch (...)
2005 aIt.remove();
2008 break;
2011 if ( bModified )
2013 // container was modified, create a new window out of it
2014 rpOut = new PopupMenu;
2015 ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer( rpOut, aEvent.ActionTriggerContainer );
2017 Change( rpOut, this );
2020 return sal_True;
2023 void SfxViewShell::TakeOwnership_Impl()
2025 // currently there is only one reason to take Ownership: a hidden frame is printed
2026 // so the ViewShell will check this on EndPrint (->prnmon.cxx)
2027 pImp->m_bGotOwnership = true;
2030 void SfxViewShell::TakeFrameOwnership_Impl()
2032 // currently there is only one reason to take Ownership: a hidden frame is printed
2033 // so the ViewShell will check this on EndPrint (->prnmon.cxx)
2034 pImp->m_bGotFrameOwnership = true;
2037 long SfxViewShell::HandleNotifyEvent_Impl( NotifyEvent& rEvent )
2039 if (pImp->m_pController.is())
2040 return pImp->m_pController->HandleEvent_Impl( rEvent );
2041 return 0;
2044 sal_Bool SfxViewShell::HasKeyListeners_Impl()
2046 return (pImp->m_pController.is())
2047 ? pImp->m_pController->HasKeyListeners_Impl() : sal_False;
2050 sal_Bool SfxViewShell::HasMouseClickListeners_Impl()
2052 return (pImp->m_pController.is())
2053 ? pImp->m_pController->HasMouseClickListeners_Impl() : sal_False;
2056 sal_Bool SfxViewShell::Escape()
2058 return GetViewFrame()->GetBindings().Execute( SID_TERMINATE_INPLACEACTIVATION );
2061 Reference< view::XRenderable > SfxViewShell::GetRenderable()
2063 Reference< view::XRenderable >xRender;
2064 SfxObjectShell* pObj = GetObjectShell();
2065 if( pObj )
2067 Reference< frame::XModel > xModel( pObj->GetModel() );
2068 if( xModel.is() )
2069 xRender = Reference< view::XRenderable >( xModel, UNO_QUERY );
2071 return xRender;
2074 uno::Reference< datatransfer::clipboard::XClipboardNotifier > SfxViewShell::GetClipboardNotifier()
2076 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClipboardNotifier;
2077 if ( GetViewFrame() )
2078 xClipboardNotifier = uno::Reference< datatransfer::clipboard::XClipboardNotifier >(
2079 GetViewFrame()->GetWindow().GetClipboard(), uno::UNO_QUERY );
2081 return xClipboardNotifier;
2084 void SfxViewShell::AddRemoveClipboardListener( const uno::Reference < datatransfer::clipboard::XClipboardListener >& rClp, sal_Bool bAdd )
2088 if ( GetViewFrame() )
2090 uno::Reference< datatransfer::clipboard::XClipboard > xClipboard( GetViewFrame()->GetWindow().GetClipboard() );
2091 if( xClipboard.is() )
2093 uno::Reference< datatransfer::clipboard::XClipboardNotifier > xClpbrdNtfr( xClipboard, uno::UNO_QUERY );
2094 if( xClpbrdNtfr.is() )
2096 if( bAdd )
2097 xClpbrdNtfr->addClipboardListener( rClp );
2098 else
2099 xClpbrdNtfr->removeClipboardListener( rClp );
2104 catch (const uno::Exception&)
2109 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */