blob: fa0d72b39abb4361ca1b25da49d8b7a2394e5abf [file] [log] [blame]
/**************************************************************
*
* 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 ?!
}