| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sfx2.hxx" |
| |
| #include "impviewframe.hxx" |
| #include "statcach.hxx" |
| #include "sfx2/viewfac.hxx" |
| #include "workwin.hxx" |
| |
| #include "sfx2/app.hxx" |
| #include "sfx2/bindings.hxx" |
| #include "sfx2/ctrlitem.hxx" |
| #include "sfx2/dispatch.hxx" |
| #include "sfx2/docfac.hxx" |
| #include "sfx2/docfile.hxx" |
| #include "sfx2/objitem.hxx" |
| #include "sfx2/objsh.hxx" |
| #include "sfx2/request.hxx" |
| #include "sfx2/viewfrm.hxx" |
| #include "sfx2/viewsh.hxx" |
| |
| #include <com/sun/star/beans/NamedValue.hpp> |
| #include <com/sun/star/beans/XMaterialHolder.hpp> |
| #include <com/sun/star/util/XCloseable.hpp> |
| |
| #include <comphelper/componentcontext.hxx> |
| #include <comphelper/namedvaluecollection.hxx> |
| #include <comphelper/processfactory.hxx> |
| #include <svtools/asynclink.hxx> |
| #include <svl/eitem.hxx> |
| #include <svl/intitem.hxx> |
| #include <svl/rectitem.hxx> |
| #include <svl/stritem.hxx> |
| #include <tools/diagnose_ex.h> |
| #include <tools/urlobj.hxx> |
| #include <unotools/bootstrap.hxx> |
| #include <unotools/configmgr.hxx> |
| #include <vcl/window.hxx> |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::frame; |
| using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::beans; |
| using ::com::sun::star::lang::XMultiServiceFactory; |
| using ::com::sun::star::lang::XComponent; |
| |
| //------------------------------------------------------------------------ |
| |
| static ::rtl::OUString GetModuleName_Impl( const ::rtl::OUString& sDocService ) |
| { |
| uno::Reference< container::XNameAccess > xMM( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager")), uno::UNO_QUERY ); |
| ::rtl::OUString sVar; |
| if ( !xMM.is() ) |
| return sVar; |
| |
| try |
| { |
| ::comphelper::NamedValueCollection aAnalyzer( xMM->getByName( sDocService ) ); |
| sVar = aAnalyzer.getOrDefault( "ooSetupFactoryUIName", ::rtl::OUString() ); |
| } |
| catch( uno::Exception& ) |
| { |
| sVar = ::rtl::OUString(); |
| } |
| |
| return sVar; |
| } |
| |
| //-------------------------------------------------------------------- |
| void SfxFrameViewWindow_Impl::StateChanged( StateChangedType nStateChange ) |
| { |
| if ( nStateChange == STATE_CHANGE_INITSHOW ) |
| { |
| SfxObjectShell* pDoc = pFrame->GetObjectShell(); |
| if ( pDoc && !pFrame->IsVisible() ) |
| pFrame->Show(); |
| |
| pFrame->Resize(); |
| } |
| else |
| Window::StateChanged( nStateChange ); |
| } |
| |
| void SfxFrameViewWindow_Impl::Resize() |
| { |
| if ( IsReallyVisible() || IsReallyShown() || GetOutputSizePixel().Width() ) |
| pFrame->Resize(); |
| } |
| |
| static String _getTabString() |
| { |
| String result; |
| |
| Reference < XMaterialHolder > xHolder( |
| ::comphelper::getProcessServiceFactory()->createInstance( |
| DEFINE_CONST_UNICODE("com.sun.star.tab.tabreg") ), UNO_QUERY ); |
| if (xHolder.is()) |
| { |
| rtl::OUString aTabString; |
| Sequence< NamedValue > sMaterial; |
| if (xHolder->getMaterial() >>= sMaterial) { |
| for (int i=0; i < sMaterial.getLength(); i++) { |
| if ((sMaterial[i].Name.equalsAscii("title")) && |
| (sMaterial[i].Value >>= aTabString)) |
| { |
| result += ' '; |
| result += String(aTabString); |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| //======================================================================== |
| |
| //-------------------------------------------------------------------- |
| String SfxViewFrame::UpdateTitle() |
| |
| /* [Beschreibung] |
| |
| Mit dieser Methode kann der SfxViewFrame gezwungen werden, sich sofort |
| den neuen Titel vom der <SfxObjectShell> zu besorgen. |
| |
| [Anmerkung] |
| |
| Dies ist z.B. dann notwendig, wenn man der SfxObjectShell als SfxListener |
| zuh"ort und dort auf den <SfxSimpleHint> SFX_HINT_TITLECHANGED reagieren |
| m"ochte, um dann die Titel seiner Views abzufragen. Diese Views (SfxTopViewFrames) |
| jedoch sind ebenfalls SfxListener und da die Reihenfolge der Benachrichtigung |
| nicht feststeht, mu\s deren Titel-Update vorab erzwungen werden. |
| |
| |
| [Beispiel] |
| |
| void SwDocShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) |
| { |
| if ( rHint.IsA(TYPE(SfxSimpleHint)) ) |
| { |
| switch( ( (SfxSimpleHint&) rHint ).GetId() ) |
| { |
| case SFX_HINT_TITLECHANGED: |
| for ( SfxViewFrame *pTop = SfxViewFrame::GetFirst( this ); |
| pTop; |
| pTop = SfxViewFrame::GetNext( this ); |
| { |
| pTop->UpdateTitle(); |
| ... pTop->GetName() ... |
| } |
| break; |
| ... |
| } |
| } |
| } |
| */ |
| |
| { |
| DBG_CHKTHIS(SfxViewFrame, 0); |
| |
| const SfxObjectFactory &rFact = GetObjectShell()->GetFactory(); |
| pImp->aFactoryName = String::CreateFromAscii( rFact.GetShortName() ); |
| |
| SfxObjectShell *pObjSh = GetObjectShell(); |
| if ( !pObjSh ) |
| return String(); |
| |
| // if ( pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) |
| // // kein UpdateTitle mit Embedded-ObjectShell |
| // return String(); |
| |
| const SfxMedium *pMedium = pObjSh->GetMedium(); |
| String aURL; |
| GetFrame(); // -Wall required?? |
| if ( pObjSh->HasName() ) |
| { |
| INetURLObject aTmp( pMedium->GetName() ); |
| aURL = aTmp.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); |
| } |
| |
| if ( aURL != pImp->aActualURL ) |
| // URL hat sich ge"andert |
| pImp->aActualURL = aURL; |
| |
| // gibt es noch eine weitere View? |
| sal_uInt16 nViews=0; |
| for ( SfxViewFrame *pView= GetFirst(pObjSh); |
| pView && nViews<2; |
| pView = GetNext(*pView,pObjSh) ) |
| if ( ( pView->GetFrameType() & SFXFRAME_HASTITLE ) && |
| !IsDowning_Impl()) |
| nViews++; |
| |
| // Titel des Fensters |
| String aTitle; |
| if ( nViews == 2 || pImp->nDocViewNo > 1 ) |
| // dann die Nummer dranh"angen |
| aTitle = pObjSh->UpdateTitle( NULL, pImp->nDocViewNo ); |
| else |
| aTitle = pObjSh->UpdateTitle(); |
| |
| // Name des SbxObjects |
| String aSbxName = pObjSh->SfxShell::GetName(); |
| if ( IsVisible() ) |
| { |
| aSbxName += ':'; |
| aSbxName += String::CreateFromInt32(pImp->nDocViewNo); |
| } |
| |
| SetName( aSbxName ); |
| pImp->aFrameTitle = aTitle; |
| GetBindings().Invalidate( SID_FRAMETITLE ); |
| GetBindings().Invalidate( SID_CURRENT_URL ); |
| |
| ::rtl::OUString aProductName; |
| ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::PRODUCTNAME) >>= aProductName; |
| |
| aTitle += String::CreateFromAscii( " - " ); |
| aTitle += String(aProductName); |
| aTitle += ' '; |
| ::rtl::OUString aDocServiceName( GetObjectShell()->GetFactory().GetDocumentServiceName() ); |
| aTitle += String( GetModuleName_Impl( aDocServiceName ) ); |
| #ifdef DBG_UTIL |
| ::rtl::OUString aDefault; |
| aTitle += DEFINE_CONST_UNICODE(" ["); |
| String aVerId( utl::Bootstrap::getBuildIdData( aDefault )); |
| aTitle += aVerId; |
| aTitle += ']'; |
| #endif |
| |
| // append TAB string if available |
| aTitle += _getTabString(); |
| |
| GetBindings().Invalidate( SID_NEWDOCDIRECT ); |
| |
| /* AS_TITLE |
| Window* pWindow = GetFrame()->GetTopWindow_Impl(); |
| if ( pWindow && pWindow->GetText() != aTitle ) |
| pWindow->SetText( aTitle ); |
| */ |
| return aTitle; |
| } |
| |
| void SfxViewFrame::Exec_Impl(SfxRequest &rReq ) |
| { |
| // Wenn gerade die Shells ausgetauscht werden... |
| if ( !GetObjectShell() || !GetViewShell() ) |
| return; |
| |
| switch ( rReq.GetSlot() ) |
| { |
| case SID_SHOWPOPUPS : |
| { |
| SFX_REQUEST_ARG(rReq, pShowItem, SfxBoolItem, SID_SHOWPOPUPS, sal_False); |
| sal_Bool bShow = pShowItem ? pShowItem->GetValue() : sal_True; |
| SFX_REQUEST_ARG(rReq, pIdItem, SfxUInt16Item, SID_CONFIGITEMID, sal_False); |
| sal_uInt16 nId = pIdItem ? pIdItem->GetValue() : 0; |
| |
| // ausfuehren |
| SfxWorkWindow *pWorkWin = GetFrame().GetWorkWindow_Impl(); |
| if ( bShow ) |
| { |
| // Zuerst die Floats auch anzeigbar machen |
| pWorkWin->MakeChildsVisible_Impl( bShow ); |
| GetDispatcher()->Update_Impl( sal_True ); |
| |
| // Dann anzeigen |
| GetBindings().HidePopups( !bShow ); |
| } |
| else |
| { |
| // Alles hiden |
| SfxBindings *pBind = &GetBindings(); |
| while ( pBind ) |
| { |
| pBind->HidePopupCtrls_Impl( !bShow ); |
| pBind = pBind->GetSubBindings_Impl(); |
| } |
| |
| pWorkWin->HidePopups_Impl( !bShow, sal_True, nId ); |
| pWorkWin->MakeChildsVisible_Impl( bShow ); |
| } |
| |
| Invalidate( rReq.GetSlot() ); |
| rReq.Done(); |
| break; |
| } |
| |
| case SID_ACTIVATE: |
| { |
| MakeActive_Impl( sal_True ); |
| rReq.SetReturnValue( SfxObjectItem( 0, this ) ); |
| break; |
| } |
| |
| case SID_NEWDOCDIRECT : |
| { |
| SFX_REQUEST_ARG( rReq, pFactoryItem, SfxStringItem, SID_NEWDOCDIRECT, sal_False); |
| String aFactName; |
| if ( pFactoryItem ) |
| aFactName = pFactoryItem->GetValue(); |
| else if ( pImp->aFactoryName.Len() ) |
| aFactName = pImp->aFactoryName; |
| else |
| { |
| DBG_ERROR("Missing argument!"); |
| break; |
| } |
| |
| SfxRequest aReq( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, GetPool() ); |
| String aFact = String::CreateFromAscii("private:factory/"); |
| aFact += aFactName; |
| aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) ); |
| aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, &GetFrame() ) ); |
| aReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii( "_blank" ) ) ); |
| SFX_APP()->ExecuteSlot( aReq ); |
| const SfxViewFrameItem* pItem = PTR_CAST( SfxViewFrameItem, aReq.GetReturnValue() ); |
| if ( pItem ) |
| rReq.SetReturnValue( SfxFrameItem( 0, pItem->GetFrame() ) ); |
| break; |
| } |
| |
| case SID_CLOSEWIN: |
| { |
| // disable CloseWin, if frame is not a task |
| Reference < XCloseable > xTask( GetFrame().GetFrameInterface(), UNO_QUERY ); |
| if ( !xTask.is() ) |
| break; |
| |
| if ( GetViewShell()->PrepareClose() ) |
| { |
| // weitere Views auf dasselbe Doc? |
| SfxObjectShell *pDocSh = GetObjectShell(); |
| int bOther = sal_False; |
| for ( const SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocSh ); |
| !bOther && pFrame; |
| pFrame = SfxViewFrame::GetNext( *pFrame, pDocSh ) ) |
| bOther = (pFrame != this); |
| |
| // Doc braucht nur gefragt zu werden, wenn keine weitere View |
| sal_Bool bClosed = sal_False; |
| sal_Bool bUI = sal_True; |
| if ( ( bOther || pDocSh->PrepareClose( bUI ) ) ) |
| { |
| if ( !bOther ) |
| pDocSh->SetModified( sal_False ); |
| rReq.Done(); // unbedingt vor Close() rufen! |
| bClosed = sal_False; |
| try |
| { |
| xTask->close(sal_True); |
| bClosed = sal_True; |
| } |
| catch( CloseVetoException& ) |
| { |
| bClosed = sal_False; |
| } |
| } |
| |
| rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bClosed )); |
| } |
| return; |
| } |
| } |
| |
| rReq.Done(); |
| } |
| |
| void SfxViewFrame::GetState_Impl( SfxItemSet &rSet ) |
| { |
| SfxObjectShell *pDocSh = GetObjectShell(); |
| |
| if ( !pDocSh ) |
| return; |
| |
| const sal_uInt16 *pRanges = rSet.GetRanges(); |
| DBG_ASSERT(pRanges, "Set ohne Bereich"); |
| while ( *pRanges ) |
| { |
| for ( sal_uInt16 nWhich = *pRanges++; nWhich <= *pRanges; ++nWhich ) |
| { |
| switch(nWhich) |
| { |
| case SID_NEWDOCDIRECT : |
| { |
| if ( pImp->aFactoryName.Len() ) |
| { |
| String aFact = String::CreateFromAscii("private:factory/"); |
| aFact += pImp->aFactoryName; |
| rSet.Put( SfxStringItem( nWhich, aFact ) ); |
| } |
| break; |
| } |
| |
| case SID_NEWWINDOW: |
| rSet.DisableItem(nWhich); |
| break; |
| |
| case SID_CLOSEWIN: |
| { |
| // disable CloseWin, if frame is not a task |
| Reference < XCloseable > xTask( GetFrame().GetFrameInterface(), UNO_QUERY ); |
| if ( !xTask.is() ) |
| rSet.DisableItem(nWhich); |
| break; |
| } |
| |
| case SID_SHOWPOPUPS : |
| break; |
| |
| case SID_OBJECT: |
| if ( GetViewShell() && GetViewShell()->GetVerbs().getLength() && !GetObjectShell()->IsInPlaceActive() ) |
| { |
| uno::Any aAny; |
| aAny <<= GetViewShell()->GetVerbs(); |
| rSet.Put( SfxUnoAnyItem( sal_uInt16( SID_OBJECT ), aAny ) ); |
| } |
| else |
| rSet.DisableItem( SID_OBJECT ); |
| break; |
| |
| default: |
| DBG_ERROR( "invalid message-id" ); |
| } |
| } |
| ++pRanges; |
| } |
| } |
| |
| void SfxViewFrame::INetExecute_Impl( SfxRequest &rRequest ) |
| { |
| sal_uInt16 nSlotId = rRequest.GetSlot(); |
| switch( nSlotId ) |
| { |
| case SID_BROWSE_FORWARD: |
| case SID_BROWSE_BACKWARD: |
| OSL_ENSURE( false, "SfxViewFrame::INetExecute_Impl: SID_BROWSE_FORWARD/BACKWARD are dead!" ); |
| break; |
| case SID_CREATELINK: |
| { |
| /*! (pb) we need new implementation to create a link |
| */ |
| break; |
| } |
| case SID_FOCUSURLBOX: |
| { |
| SfxStateCache *pCache = GetBindings().GetAnyStateCache_Impl( SID_OPENURL ); |
| if( pCache ) |
| { |
| SfxControllerItem* pCtrl = pCache->GetItemLink(); |
| while( pCtrl ) |
| { |
| pCtrl->StateChanged( SID_FOCUSURLBOX, SFX_ITEM_UNKNOWN, 0 ); |
| pCtrl = pCtrl->GetItemLink(); |
| } |
| } |
| } |
| } |
| |
| // Recording |
| rRequest.Done(); |
| } |
| |
| void SfxViewFrame::INetState_Impl( SfxItemSet &rItemSet ) |
| { |
| rItemSet.DisableItem( SID_BROWSE_FORWARD ); |
| rItemSet.DisableItem( SID_BROWSE_BACKWARD ); |
| |
| // Add/SaveToBookmark bei BASIC-IDE, QUERY-EDITOR etc. disablen |
| SfxObjectShell *pDocSh = GetObjectShell(); |
| sal_Bool bPseudo = pDocSh && !( pDocSh->GetFactory().GetFlags() & SFXOBJECTSHELL_HASOPENDOC ); |
| sal_Bool bEmbedded = pDocSh && pDocSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED; |
| if ( !pDocSh || bPseudo || bEmbedded || !pDocSh->HasName() ) |
| rItemSet.DisableItem( SID_CREATELINK ); |
| } |
| |
| void SfxViewFrame::SetZoomFactor( const Fraction &rZoomX, const Fraction &rZoomY ) |
| { |
| GetViewShell()->SetZoomFactor( rZoomX, rZoomY ); |
| } |
| |
| void SfxViewFrame::Activate( sal_Bool bMDI ) |
| { |
| DBG_ASSERT(GetViewShell(), "Keine Shell"); |
| if ( bMDI ) |
| pImp->bActive = sal_True; |
| //(mba): hier evtl. wie in Beanframe NotifyEvent ?! |
| } |
| |
| void SfxViewFrame::Deactivate( sal_Bool bMDI ) |
| { |
| DBG_ASSERT(GetViewShell(), "Keine Shell"); |
| if ( bMDI ) |
| pImp->bActive = sal_False; |
| //(mba): hier evtl. wie in Beanframe NotifyEvent ?! |
| } |