/************************************************************** * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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 zu besorgen. [Anmerkung] Dies ist z.B. dann notwendig, wenn man der SfxObjectShell als SfxListener zuh"ort und dort auf den 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 ?! }