/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sfx2.hxx" #ifndef GCC #endif #include #include #include #include #include #include "workwin.hxx" #include #include "arrdecl.hxx" #include #include #include #include #include #include "splitwin.hxx" #include #include "sfxresid.hxx" #include #include // SFX_ITEMSET_SET #include #include #include #include #include #include #include #include #include #ifndef _SFXEITEM_HXX //autogen #include #endif #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; namespace css = ::com::sun::star; struct ResIdToResName { USHORT nId; const char* pName; }; static const ResIdToResName pToolBarResToName[] = { { 558, "fullscreenbar" }, { 560, "standardbar", }, { 18001, "formsnavigationbar" }, { 18002, "formsfilterbar" }, { 18003, "formtextobjectbar" }, { 18004, "formcontrols" }, { 18005, "moreformcontrols" }, { 18006, "formdesign" }, { 20050, "toolbar" }, //math { 30001, "objectbar" }, //chart { 30513, "toolbar" }, //chart { 25005, "textobjectbar" }, //calc { 25053, "drawobjectbar" }, { 25054, "graphicobjectbar" }, { 25001, "formatobjectbar" }, { 25006, "previewbar" }, { 25035, "toolbar" }, //calc { 23015, "bezierobjectbar" }, //draw/impress { 23019, "gluepointsobjectbar" }, { 23030, "graphicobjectbar" }, { 23013, "drawingobjectbar" }, //impress { 23016, "textobjectbar" }, //impress { 23028, "textobjectbar" }, //draw { 23011, "toolbar" }, //impress { 23020, "optionsbar" }, { 23021, "commontaskbar" }, { 23025, "toolbar" }, //draw { 23026, "optionsbar" }, { 23027, "drawingobjectbar" }, //draw { 23017, "outlinetoolbar" }, //impress { 23012, "slideviewtoolbar" }, { 23014, "slideviewobjectbar" }, { 23283, "bezierobjectbar" }, //writer { 23269, "drawingobjectbar" }, { 23270, "drawtextobjectbar" }, { 23267, "frameobjectbar" }, { 23268, "graphicobjectbar" }, { 23271, "numobjectbar" }, { 23272, "oleobjectbar" }, { 23266, "tableobjectbar" }, { 23265, "textobjectbar" }, { 20631, "previewobjectbar" }, //writer { 20402, "toolbar" }, //web { 20403, "textobjectbar" }, { 23273, "toolbar" }, //writer { 20408, "frameobjectbar" }, //web { 20410, "graphicobjectbar" }, { 20411, "oleobjectbar" }, { 14850, "macrobar" }, { 10987, "fontworkobjectbar" }, //global { 10986, "extrusionobjectbar" }, { 23022, "formsobjectbar" }, { 23310, "viewerbar" }, //writer (plugin) { 25000, "viewerbar" }, //calc (plugin) { 23023, "viewerbar" }, //impress(plugin) { 23024, "viewerbar" }, //draw (plugin) { 23031, "mediaobjectbar" }, //draw/impress { 25060, "mediaobjectbar" }, //calc { 23311, "mediaobjectbar" }, //writer { 0, "" } }; DBG_NAME(SfxWorkWindow) //SV_IMPL_OBJARR( SfxObjectBarArr_Impl, SfxObjectBar_Impl ); //==================================================================== // Sortiert die Children nach ihrem Alignment // Reihenfolge entspricht der im enum SfxChildAlignment (->CHILDWIN.HXX). // // Hilfe, um die "Anderungen am Alignment kompatibal zu machen! SFX_IMPL_XINTERFACE_3( LayoutManagerListener, OWeakObject, ::com::sun::star::frame::XLayoutManagerListener, ::com::sun::star::lang::XEventListener, ::com::sun::star::lang::XComponent ) SFX_IMPL_XTYPEPROVIDER_3( LayoutManagerListener, ::com::sun::star::frame::XLayoutManagerListener, ::com::sun::star::lang::XEventListener, ::com::sun::star::lang::XComponent ) LayoutManagerListener::LayoutManagerListener( SfxWorkWindow* pWrkWin ) : m_bHasFrame( sal_False ), m_pWrkWin( pWrkWin ), m_aLayoutManagerPropName( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )) { } LayoutManagerListener::~LayoutManagerListener() { } void LayoutManagerListener::setFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) { ::vos::OGuard aGuard( Application::GetSolarMutex() ); if ( m_pWrkWin && !m_bHasFrame ) { m_xFrame = xFrame; m_bHasFrame = sal_True; if ( xFrame.is() ) { css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY ); css::uno::Reference< css::frame::XLayoutManagerEventBroadcaster > xLayoutManager; if ( xPropSet.is() ) { try { Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); aValue >>= xLayoutManager; if ( xLayoutManager.is() ) xLayoutManager->addLayoutManagerEventListener( css::uno::Reference< css::frame::XLayoutManagerListener >( static_cast< OWeakObject* >( this ), css::uno::UNO_QUERY )); xPropSet = css::uno::Reference< css::beans::XPropertySet >( xLayoutManager, UNO_QUERY ); if ( xPropSet.is() ) { aValue = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LockCount" )) ); aValue >>= m_pWrkWin->m_nLock; } } catch ( css::lang::DisposedException& ) { } catch ( css::uno::RuntimeException& e ) { throw e; } catch ( css::uno::Exception& ) { } } } } } //--------------------------------------------------------------------------------------------------------- // XComponent //--------------------------------------------------------------------------------------------------------- void SAL_CALL LayoutManagerListener::addEventListener( const css::uno::Reference< css::lang::XEventListener >& ) throw (::com::sun::star::uno::RuntimeException) { // do nothing, only internal class } void SAL_CALL LayoutManagerListener::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& ) throw (::com::sun::star::uno::RuntimeException) { // do nothing, only internal class } void SAL_CALL LayoutManagerListener::dispose() throw( css::uno::RuntimeException ) { ::vos::OGuard aGuard( Application::GetSolarMutex() ); // reset member m_pWrkWin = 0; css::uno::Reference< css::frame::XFrame > xFrame( m_xFrame.get(), css::uno::UNO_QUERY ); if ( xFrame.is() ) { m_xFrame = css::uno::Reference< css::frame::XFrame >(); m_bHasFrame = sal_False; css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY ); css::uno::Reference< css::frame::XLayoutManagerEventBroadcaster > xLayoutManager; if ( xPropSet.is() ) { try { css::uno::Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); aValue >>= xLayoutManager; // remove as listener from layout manager if ( xLayoutManager.is() ) xLayoutManager->removeLayoutManagerEventListener( css::uno::Reference< css::frame::XLayoutManagerListener >( static_cast< OWeakObject* >( this ), css::uno::UNO_QUERY )); } catch ( css::lang::DisposedException& ) { } catch ( css::uno::RuntimeException& e ) { throw e; } catch ( css::uno::Exception& ) { } } } } //--------------------------------------------------------------------------------------------------------- // XEventListener //--------------------------------------------------------------------------------------------------------- void SAL_CALL LayoutManagerListener::disposing( const css::lang::EventObject& ) throw( css::uno::RuntimeException ) { ::vos::OGuard aGuard( Application::GetSolarMutex() ); m_pWrkWin = 0; m_bHasFrame = sal_False; m_xFrame = css::uno::Reference< css::frame::XFrame >(); } //--------------------------------------------------------------------------------------------------------- // XLayoutManagerEventListener //--------------------------------------------------------------------------------------------------------- void SAL_CALL LayoutManagerListener::layoutEvent( const css::lang::EventObject&, ::sal_Int16 eLayoutEvent, const css::uno::Any& ) throw (css::uno::RuntimeException) { ::vos::OGuard aGuard( Application::GetSolarMutex() ); if ( m_pWrkWin ) { if ( eLayoutEvent == css::frame::LayoutManagerEvents::VISIBLE ) { m_pWrkWin->MakeVisible_Impl( TRUE ); m_pWrkWin->ShowChilds_Impl(); m_pWrkWin->ArrangeChilds_Impl( TRUE ); } else if ( eLayoutEvent == css::frame::LayoutManagerEvents::INVISIBLE ) { m_pWrkWin->MakeVisible_Impl( FALSE ); m_pWrkWin->HideChilds_Impl(); m_pWrkWin->ArrangeChilds_Impl( TRUE ); } else if ( eLayoutEvent == css::frame::LayoutManagerEvents::LOCK ) { m_pWrkWin->Lock_Impl( TRUE ); } else if ( eLayoutEvent == css::frame::LayoutManagerEvents::UNLOCK ) { m_pWrkWin->Lock_Impl( FALSE ); } } } //==================================================================== typedef std::hash_map< sal_Int32, rtl::OUString > ToolBarResIdToResourceURLMap; static sal_Bool bMapInitialized = sal_False; static ToolBarResIdToResourceURLMap aResIdToResourceURLMap; static rtl::OUString GetResourceURLFromResId( USHORT nResId ) { if ( !bMapInitialized ) { osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; if ( !bMapInitialized ) { sal_Int32 nIndex( 0 ); while ( pToolBarResToName[nIndex].nId != 0 ) { rtl::OUString aResourceURL( rtl::OUString::createFromAscii( pToolBarResToName[nIndex].pName )); aResIdToResourceURLMap.insert( ToolBarResIdToResourceURLMap::value_type( sal_Int32( pToolBarResToName[nIndex].nId ), aResourceURL )); ++nIndex; } bMapInitialized = sal_True; } } ToolBarResIdToResourceURLMap::const_iterator pIter = aResIdToResourceURLMap.find( nResId ); if ( pIter != aResIdToResourceURLMap.end() ) return pIter->second; else return rtl::OUString(); } BOOL IsAppWorkWinToolbox_Impl( USHORT nPos ) { switch ( nPos ) { case SFX_OBJECTBAR_APPLICATION : case SFX_OBJECTBAR_MACRO: case SFX_OBJECTBAR_FULLSCREEN: return TRUE; default: return FALSE; } } USHORT TbxMatch( USHORT nPos ) { switch ( nPos ) { case SFX_OBJECTBAR_APPLICATION : return 0; case SFX_OBJECTBAR_OPTIONS: return 1; case SFX_OBJECTBAR_MACRO: return 2; case SFX_OBJECTBAR_OBJECT: return 3; case SFX_OBJECTBAR_TOOLS: return 4; case SFX_OBJECTBAR_FULLSCREEN: case SFX_OBJECTBAR_COMMONTASK: case SFX_OBJECTBAR_RECORDING: return nPos+1; default: return nPos; } } USHORT ChildAlignValue(SfxChildAlignment eAlign) { USHORT ret = 17; switch (eAlign) { case SFX_ALIGN_HIGHESTTOP: ret = 1; break; case SFX_ALIGN_LOWESTBOTTOM: ret = 2; break; case SFX_ALIGN_FIRSTLEFT: ret = 3; break; case SFX_ALIGN_LASTRIGHT: ret = 4; break; case SFX_ALIGN_LEFT: ret = 5; break; case SFX_ALIGN_RIGHT: ret = 6; break; case SFX_ALIGN_FIRSTRIGHT: ret = 7; break; case SFX_ALIGN_LASTLEFT: ret = 8; break; case SFX_ALIGN_TOP: ret = 9; break; case SFX_ALIGN_BOTTOM: ret = 10; break; case SFX_ALIGN_TOOLBOXTOP: ret = 11; break; case SFX_ALIGN_TOOLBOXBOTTOM: ret = 12; break; case SFX_ALIGN_LOWESTTOP: ret = 13; break; case SFX_ALIGN_HIGHESTBOTTOM: ret = 14; break; case SFX_ALIGN_TOOLBOXLEFT: ret = 15; break; case SFX_ALIGN_TOOLBOXRIGHT: ret = 16; break; case SFX_ALIGN_NOALIGNMENT: break; // -Wall not handled... } return ret; } USHORT ChildTravelValue( SfxChildAlignment eAlign ) { USHORT ret = 17; switch (eAlign) { case SFX_ALIGN_FIRSTLEFT: ret = 1; break; case SFX_ALIGN_LEFT: ret = 2; break; case SFX_ALIGN_LASTLEFT: ret = 3; break; case SFX_ALIGN_TOOLBOXLEFT: ret = 4; break; case SFX_ALIGN_HIGHESTTOP: ret = 5; break; case SFX_ALIGN_TOP: ret = 6; break; case SFX_ALIGN_TOOLBOXTOP: ret = 7; break; case SFX_ALIGN_LOWESTTOP: ret = 8; break; case SFX_ALIGN_HIGHESTBOTTOM: ret = 9; break; case SFX_ALIGN_TOOLBOXBOTTOM: ret = 10; break; case SFX_ALIGN_BOTTOM: ret = 11; break; case SFX_ALIGN_LOWESTBOTTOM: ret = 12; break; case SFX_ALIGN_TOOLBOXRIGHT: ret = 13; break; case SFX_ALIGN_FIRSTRIGHT: ret = 14; break; case SFX_ALIGN_RIGHT: ret = 15; break; case SFX_ALIGN_LASTRIGHT: ret = 16; break; case SFX_ALIGN_NOALIGNMENT: break; // -Wall not handled. } return ret; } void SfxWorkWindow::Sort_Impl() { aSortedList.Remove(0, aSortedList.Count()); for (USHORT i=0; iCount(); i++) { SfxChild_Impl *pCli = (*pChilds)[i]; if (pCli) { USHORT k; for (k=0; keAlign > pCli->eAlign ) if (ChildAlignValue((*pChilds)[aSortedList[k]]->eAlign) > ChildAlignValue(pCli->eAlign)) break; aSortedList.Insert (i,k); } } bSorted = TRUE; } //==================================================================== // ctor f"ur workwin eines Frames SfxFrameWorkWin_Impl::SfxFrameWorkWin_Impl( Window *pWin, SfxFrame *pFrm, SfxFrame* pMaster ) : SfxWorkWindow( pWin, pFrm->GetCurrentViewFrame()->GetBindings(), pFrm->GetParentFrame() ? pFrm->GetParentFrame()->GetWorkWindow_Impl() : NULL ) , pMasterFrame( pMaster ) , pFrame( pFrm ) { pConfigShell = pFrm->GetCurrentViewFrame(); if ( pConfigShell && pConfigShell->GetObjectShell() ) { bShowStatusBar = ( !pConfigShell->GetObjectShell()->IsInPlaceActive() ); bDockingAllowed = sal_True; bInternalDockingAllowed = sal_True; } // Die ben"otigten SplitWindows (je eins f"ur jede Seite) werden erzeugt for ( USHORT n=0; nSetWorkWindow_Impl( this ); pChildWins = new SfxChildWindows_Impl; pChilds = new SfxChildList_Impl; // F"ur die ObjectBars wird ein fester Platz in der ChildList reserviert, // damit sie immer in einer definierten Reihenfolge kommen. SfxChild_Impl* pChild=0; for (USHORT n=0; n < SFX_OBJECTBAR_MAX; ++n) pChilds->Insert(0,pChild); // create and initialize layout manager listener Reference< com::sun::star::frame::XFrame > xFrame = GetFrameInterface(); LayoutManagerListener* pLayoutManagerListener = new LayoutManagerListener( this ); m_xLayoutManagerListener = css::uno::Reference< css::lang::XComponent >( static_cast< cppu::OWeakObject* >( pLayoutManagerListener ), css::uno::UNO_QUERY ); pLayoutManagerListener->setFrame( xFrame ); } //==================================================================== // dtor SfxWorkWindow::~SfxWorkWindow() { DBG_DTOR(SfxWorkWindow, 0); // SplitWindows l"oschen for ( USHORT n=0; nGetWindowCount()) ReleaseChild_Impl(*p); delete p; } // Hilfsstruktur f"ur Child-Windows l"oschen DBG_ASSERT( pChilds->Count() == 0, "dangling childs" ); delete pChilds; delete pChildWins; if ( m_xLayoutManagerListener.is() ) m_xLayoutManagerListener->dispose(); } SystemWindow* SfxWorkWindow::GetTopWindow() const { Window* pRet = pWorkWin; while ( pRet && !pRet->IsSystemWindow() ) pRet = pRet->GetParent(); return (SystemWindow*) pRet; } void SfxWorkWindow::Lock_Impl( BOOL bLock ) { if ( bLock ) m_nLock++; else --m_nLock; if ( m_nLock<0 ) { DBG_ERROR("Lock count underflow!"); m_nLock = 0; } if ( !m_nLock ) ArrangeChilds_Impl(); } void SfxWorkWindow::ChangeWindow_Impl( Window *pNew ) { Window *pOld = pWorkWin; pWorkWin = pNew; for ( USHORT nPos = 0; nPos < pChilds->Count(); ++nPos ) { SfxChild_Impl *pCli = (*pChilds)[nPos]; if ( pCli && pCli->pWin && pCli->pWin->GetParent() == pOld ) { pCli->pWin->SetParent( pNew ); } } } void SfxWorkWindow::SaveStatus_Impl() { USHORT nCount = pChildWins->Count(); for ( USHORT n=0; npWin; if (pChild) { USHORT nFlags = pCW->aInfo.nFlags; pCW->aInfo = pChild->GetInfo(); pCW->aInfo.nFlags |= nFlags; SaveStatus_Impl(pChild, pCW->aInfo); } } } //-------------------------------------------------------------------- // Hilfsmethode zum Freigeben der Childlisten. Wenn danach nicht der dtor // aufgerufen wird, sondern weiter gearbeitet wird, mu\s wie im ctor von // SfxWorkWindow noch Platz f"ur die Objectbars und SplitWindows reserviert // werden. void SfxWorkWindow::DeleteControllers_Impl() { DBG_CHKTHIS(SfxWorkWindow, 0); // SplitWindows locken (d.h. Resize-Reaktion an den // DockingWindows unterdr"ucken) USHORT n; for ( n=0; nGetWindowCount()) p->Lock(); } // Child-Windows l"oschen for ( n=0; nCount(); ) { SfxChildWin_Impl* pCW = (*pChildWins)[n]; pChildWins->Remove(n); SfxChildWindow *pChild = pCW->pWin; if (pChild) { /* USHORT nFlags = pCW->aInfo.nFlags; pCW->aInfo = pChild->GetInfo(); pCW->aInfo.nFlags |= nFlags; SaveStatus_Impl(pChild, pCW->aInfo); */ pChild->Hide(); // Wenn das ChildWindow ein direktes Childfenster ist und nicht // in einem SplitWindow liegt, am WorkWindow abmelden. // Nach TH ist eine Abmeldung am Splitwindow nicht erforderlich, // wenn dieses auch gleich mit zerst"ort wird (s.u.). if (pCW->pCli) ReleaseChild_Impl(*pChild->GetWindow()); pCW->pWin = 0; pWorkWin->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChild->GetWindow() ); pChild->Destroy(); } delete pCW; // ATTENTION: The array itself is cleared after this loop!! // Therefore we have to set every array entry to zero as it could be // accessed by calling pChild->Destroy(). // See task 128307 (Windows) // Window::NotifyAllChilds() calls SfxWorkWindow::DataChanged_Impl for // 8-bit displays (WM_QUERYPALETTECHANGED message due to focus change)!! //(*pChildWins)[n] = 0; } //pChildWins->Remove((USHORT)0, nCount); Reference< com::sun::star::frame::XFrame > xFrame = GetFrameInterface(); Reference< com::sun::star::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY ); Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; if ( xPropSet.is() ) { try { Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); aValue >>= xLayoutManager; } catch ( Exception& ) { } } if ( xLayoutManager.is() ) { xLayoutManager->reset(); // StatusBar l"oschen ResetStatusBar_Impl(); // ObjectBars l"oschen( zuletzt, damit pChilds nicht tote Pointer enh"alt ) for ( USHORT i = 0; i < aObjBarList.size(); i++ ) { // Nicht jede Position mu\s belegt sein USHORT nId = aObjBarList[i].nId; if ( nId ) aObjBarList[i].nId = 0; } } // ObjectBars werden alle auf einmal released, da sie einen // festen zusammenh"angenden Bereich im Array pChilds belegen pChilds->Remove(0, SFX_OBJECTBAR_MAX); bSorted = FALSE; nChilds = 0; } //==================================================================== // Virtuelle Methode zum Anordnen der Childfenster. void SfxWorkWindow::ArrangeChilds_Impl( BOOL /*bForce*/) { Arrange_Impl(); } void SfxFrameWorkWin_Impl::ArrangeChilds_Impl( BOOL bForce ) { if ( pFrame->IsClosing_Impl() || ( m_nLock && !bForce )) return; SfxInPlaceClient *pClient = 0; SfxViewFrame *pF = pFrame->GetCurrentViewFrame(); if ( pF && pF->GetViewShell() ) pClient = pF->GetViewShell()->GetIPClient(); if ( pClient ) return; aClientArea = GetTopRect_Impl(); if ( aClientArea.IsEmpty() ) return; SvBorder aBorder; if ( nChilds ) { if ( IsVisible_Impl() ) aBorder = Arrange_Impl(); } // Wenn das aktuelle Dokument der Applikation einen IPClient enth"alt, mu\s // dem dazugeh"origen Objekt durch SetTopToolFramePixel der zur Verf"ugung // stehende Platz zugeteilt werden. Das Objekt zeigt dann seine UITools an // und setzt den App-Border(->SfxInPlaceEnv_Impl::ArrangeChilds_Impl()). // Anderenfalls wird hier direkt der AppBorder gesetzt, um evtl. den Border // zu "uberschreiben, den bisher ein Objekt aus einem anderen Dokument // gesetzt hatte. // Das Objekt setzt, wenn es seine UI-Tools wegnimmt, den SetAppBorder nicht, // damit kein ObjectBar-Zappeln entsteht. // (->SfxInPlaceEnv_Impl::ArrangeChilds_Impl()) pMasterFrame->SetToolSpaceBorderPixel_Impl( aBorder ); ArrangeAutoHideWindows( NULL ); } //-------------------------------------------------------------------- SvBorder SfxWorkWindow::Arrange_Impl() /* [Beschreibung] Diese Methode ordnet alle sichtbaren ChildFenster so an, da\s die angedockten Fenster nach der Sorierreihenfolge von au\sen nach innen aneinander gesetzt werden. Wenn ein an sich sichtbares Fenster nicht mehr in die noch freie ClientArea pa\st, wird es auf "nicht sichtbar" gesetzt. */ { DBG_CHKTHIS(SfxWorkWindow, 0); aClientArea = GetTopRect_Impl(); aUpperClientArea = aClientArea; SvBorder aBorder; if ( !nChilds ) return aBorder; if (!bSorted) Sort_Impl(); Point aPos; Size aSize; Rectangle aTmp( aClientArea ); for ( USHORT n=0; npWin ) continue; // Zun"achst nehmen wir an, da\s das Fenster Platz hat pCli->nVisible |= CHILD_FITS_IN; // Nicht sichtbare Fenster "uberspringen if (pCli->nVisible != CHILD_VISIBLE) continue; if ( pCli->bResize ) aSize = pCli->aSize; else aSize = pCli->pWin->GetSizePixel(); SvBorder aTemp = aBorder; BOOL bAllowHiding = TRUE; switch ( pCli->eAlign ) { case SFX_ALIGN_HIGHESTTOP: case SFX_ALIGN_TOP: case SFX_ALIGN_TOOLBOXTOP: case SFX_ALIGN_LOWESTTOP: aSize.Width() = aTmp.GetWidth(); if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW ) aSize = ((SplitWindow *)(pCli->pWin))->CalcLayoutSizePixel( aSize ); bAllowHiding = FALSE; aBorder.Top() += aSize.Height(); aPos = aTmp.TopLeft(); aTmp.Top() += aSize.Height(); if ( pCli->eAlign == SFX_ALIGN_HIGHESTTOP ) aUpperClientArea.Top() += aSize.Height(); break; case SFX_ALIGN_LOWESTBOTTOM: case SFX_ALIGN_BOTTOM: case SFX_ALIGN_TOOLBOXBOTTOM: case SFX_ALIGN_HIGHESTBOTTOM: aSize.Width() = aTmp.GetWidth(); if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW ) aSize = ((SplitWindow *)(pCli->pWin))->CalcLayoutSizePixel( aSize ); aBorder.Bottom() += aSize.Height(); aPos = aTmp.BottomLeft(); aPos.Y() -= (aSize.Height()-1); aTmp.Bottom() -= aSize.Height(); if ( pCli->eAlign == SFX_ALIGN_LOWESTBOTTOM ) aUpperClientArea.Bottom() -= aSize.Height(); break; case SFX_ALIGN_FIRSTLEFT: case SFX_ALIGN_LEFT: case SFX_ALIGN_LASTLEFT: case SFX_ALIGN_TOOLBOXLEFT: aSize.Height() = aTmp.GetHeight(); if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW ) aSize = ((SplitWindow *)(pCli->pWin))->CalcLayoutSizePixel( aSize ); bAllowHiding = FALSE; aBorder.Left() += aSize.Width(); aPos = aTmp.TopLeft(); aTmp.Left() += aSize.Width(); if ( pCli->eAlign != SFX_ALIGN_TOOLBOXLEFT ) aUpperClientArea.Left() += aSize.Width(); break; case SFX_ALIGN_FIRSTRIGHT: case SFX_ALIGN_RIGHT: case SFX_ALIGN_LASTRIGHT: case SFX_ALIGN_TOOLBOXRIGHT: aSize.Height() = aTmp.GetHeight(); if ( pCli->pWin->GetType() == WINDOW_SPLITWINDOW ) aSize = ((SplitWindow *)(pCli->pWin))->CalcLayoutSizePixel( aSize ); aBorder.Right() += aSize.Width(); aPos = aTmp.TopRight(); aPos.X() -= (aSize.Width()-1); aTmp.Right() -= aSize.Width(); if ( pCli->eAlign != SFX_ALIGN_TOOLBOXRIGHT ) aUpperClientArea.Right() -= aSize.Width(); break; default: pCli->aSize = pCli->pWin->GetSizePixel(); pCli->bResize = FALSE; continue; } pCli->pWin->SetPosSizePixel( aPos, aSize ); pCli->bResize = FALSE; pCli->aSize = aSize; if( bAllowHiding && !RequestTopToolSpacePixel_Impl( aBorder ) ) { pCli->nVisible ^= CHILD_FITS_IN; aBorder = aTemp; } } if ( aClientArea.GetWidth() >= aBorder.Left() + aBorder.Right() ) { aClientArea.Left() += aBorder.Left(); aClientArea.Right() -= aBorder.Right(); } else { aBorder.Left() = aClientArea.Left(); aBorder.Right() = aClientArea.Right(); aClientArea.Right() = aClientArea.Left() = aTmp.Left(); } if ( aClientArea.GetHeight() >= aBorder.Top() + aBorder.Bottom() ) { aClientArea.Top() += aBorder.Top(); aClientArea.Bottom() -= aBorder.Bottom(); } else { aBorder.Top() = aClientArea.Top(); aBorder.Bottom() = aClientArea.Bottom(); aClientArea.Top() = aClientArea.Bottom() = aTmp.Top(); } return IsDockingAllowed() ? aBorder : SvBorder(); } //-------------------------------------------------------------------- // Close-Handler: die Konfiguration der ChildWindows wird gespeichert. // void SfxWorkWindow::Close_Impl() { for (USHORT n=0; nCount(); n++) { SfxChildWin_Impl *pCW = (*pChildWins)[n]; SfxChildWindow *pChild = pCW->pWin; if (pChild) { USHORT nFlags = pCW->aInfo.nFlags; pCW->aInfo = pChild->GetInfo(); pCW->aInfo.nFlags |= nFlags; SaveStatus_Impl(pChild, pCW->aInfo); } } } BOOL SfxWorkWindow::PrepareClose_Impl() { for (USHORT n=0; nCount(); n++) { SfxChildWin_Impl *pCW = (*pChildWins)[n]; SfxChildWindow *pChild = pCW->pWin; if ( pChild && !pChild->QueryClose() ) return FALSE; } return TRUE; } //-------------------------------------------------------------------- SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl( Window& rWindow, SfxChildAlignment eAlign, BOOL bCanGetFocus ) { DBG_CHKTHIS(SfxWorkWindow, 0); DBG_ASSERT( pChilds->Count() < 255, "too many childs" ); DBG_ASSERT( SfxChildAlignValid(eAlign), "invalid align" ); DBG_ASSERT( !FindChild_Impl(rWindow), "child registered more than once" ); if ( rWindow.GetParent() != pWorkWin ) rWindow.SetParent( pWorkWin ); SfxChild_Impl *pChild = new SfxChild_Impl(rWindow, rWindow.GetSizePixel(), eAlign, rWindow.IsVisible()); pChild->bCanGetFocus = bCanGetFocus; pChilds->Insert(pChilds->Count(), pChild); bSorted = FALSE; nChilds++; return (*pChilds)[pChilds->Count()-1]; } //-------------------------------------------------------------------- void SfxWorkWindow::AlignChild_Impl( Window& rWindow, const Size& rNewSize, SfxChildAlignment eAlign ) { DBG_CHKTHIS(SfxWorkWindow, 0); // DBG_ASSERT( pChilds, "aligning unregistered child" ); DBG_ASSERT( SfxChildAlignValid(eAlign), "invalid align" ); SfxChild_Impl *pChild = FindChild_Impl(rWindow); if ( pChild ) { if (pChild->eAlign != eAlign) bSorted = FALSE; pChild->eAlign = eAlign; pChild->aSize = rNewSize; pChild->bResize = TRUE; } else { DBG_ERROR( "aligning unregistered child" ); } } //-------------------------------------------------------------------- void SfxWorkWindow::ReleaseChild_Impl( Window& rWindow ) { DBG_CHKTHIS(SfxWorkWindow, 0); // DBG_ASSERT( pChilds, "releasing unregistered child" ); SfxChild_Impl *pChild = 0; USHORT nPos; for ( nPos = 0; nPos < pChilds->Count(); ++nPos ) { pChild = (*pChilds)[nPos]; if ( pChild ) if ( pChild->pWin == &rWindow ) break; } if ( nPos < pChilds->Count() ) { bSorted = FALSE; nChilds--; pChilds->Remove(nPos); delete pChild; } else { DBG_ERROR( "releasing unregistered child" ); } } //-------------------------------------------------------------------- SfxChild_Impl* SfxWorkWindow::FindChild_Impl( const Window& rWindow ) const { DBG_CHKTHIS(SfxWorkWindow, 0); SfxChild_Impl *pChild = 0; USHORT nCount = pChilds->Count(); for ( USHORT nPos = 0; nPos < nCount; ++nPos ) { pChild = (*pChilds)[nPos]; if ( pChild ) if ( pChild->pWin == &rWindow ) return pChild; } return 0; } //-------------------------------------------------------------------- void SfxWorkWindow::ShowChilds_Impl() { DBG_CHKTHIS(SfxWorkWindow, 0); bool bInvisible = ( !IsVisible_Impl() || ( !pWorkWin->IsReallyVisible() && !pWorkWin->IsReallyShown() )); SfxChild_Impl *pCli = 0; for ( USHORT nPos = 0; nPos < pChilds->Count(); ++nPos ) { SfxChildWin_Impl* pCW = 0; pCli = (*pChilds)[nPos]; if ( pCli && pCli->pWin ) { // We have to find the SfxChildWin_Impl to retrieve the // SFX_CHILDWIN flags that can influence visibility. for (USHORT n=0; nCount(); n++) { SfxChildWin_Impl* pCWin = (*pChildWins)[n]; SfxChild_Impl* pChild = pCWin->pCli; if ( pChild == pCli ) { pCW = pCWin; break; } } bool bVisible( !bInvisible ); if ( pCW ) { // Check flag SFX_CHILDWIN_NEVERHIDE that forces us to show // the child window even in situations where no child window is // visible. sal_uInt16 nFlags = pCW->aInfo.nFlags; bVisible = !bInvisible || ( bInvisible & (( nFlags & SFX_CHILDWIN_NEVERHIDE ) != 0 )); } if ( CHILD_VISIBLE == (pCli->nVisible & CHILD_VISIBLE) && bVisible ) { USHORT nFlags = pCli->bSetFocus ? 0 : SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE; switch ( pCli->pWin->GetType() ) { case RSC_DOCKINGWINDOW : ((DockingWindow*)pCli->pWin)->Show( TRUE, nFlags ); break; case RSC_SPLITWINDOW : ((SplitWindow*)pCli->pWin)->Show( TRUE, nFlags ); break; default: pCli->pWin->Show( TRUE, nFlags ); break; } pCli->bSetFocus = FALSE; } else { switch ( pCli->pWin->GetType() ) { case RSC_DOCKINGWINDOW : ((DockingWindow*)pCli->pWin)->Hide(); break; default: pCli->pWin->Hide(); break; } } } } } //-------------------------------------------------------------------- void SfxWorkWindow::HideChilds_Impl() { SfxChild_Impl *pChild = 0; for ( USHORT nPos = pChilds->Count(); nPos > 0; --nPos ) { pChild = (*pChilds)[nPos-1]; if (pChild && pChild->pWin) { switch ( pChild->pWin->GetType() ) { case RSC_DOCKINGWINDOW : ((DockingWindow*)pChild->pWin)->Hide(); break; default: pChild->pWin->Hide(); break; } } } } //------------------------------------------------------------------------ void SfxWorkWindow::ResetObjectBars_Impl() { USHORT n; for ( n = 0; n < aObjBarList.size(); n++ ) aObjBarList[n].bDestroy = sal_True; for ( n = 0; n < pChildWins->Count(); ++n ) (*pChildWins)[n]->nId = 0; } void SfxWorkWindow::NextObjectBar_Impl( USHORT ) { } USHORT SfxWorkWindow::HasNextObjectBar_Impl( USHORT, String* ) { return 0; } //------------------------------------------------------------------------ void SfxWorkWindow::SetObjectBar_Impl( USHORT nPos, sal_uInt32 nResId, SfxInterface* pIFace, const String *pName) { DBG_ASSERT( (nPos & SFX_POSITION_MASK) < SFX_OBJECTBAR_MAX, "object bar position overflow" ); USHORT nRealPos = nPos & SFX_POSITION_MASK; if ( pParent && IsAppWorkWinToolbox_Impl( nRealPos ) ) { pParent->SetObjectBar_Impl( nPos, nResId, pIFace, pName ); return; } SfxObjectBar_Impl aObjBar; aObjBar.pIFace = pIFace; aObjBar.nId = sal::static_int_cast(nResId); aObjBar.nPos = nRealPos; aObjBar.nMode = (nPos & SFX_VISIBILITY_MASK); if (pName) aObjBar.aName = *pName; else aObjBar.aName.Erase(); for ( USHORT n=0; nKnowsObjectBar_Impl( nPos ); for ( USHORT n=0; nIsClosing_Impl() ) return; SfxWorkWindow *pWork = pParent; while ( pWork ) { pWork->SfxWorkWindow::UpdateObjectBars_Impl(); pWork = pWork->GetParent_Impl(); } SfxWorkWindow::UpdateObjectBars_Impl(); // if ( pTask->IsActive() ) { pWork = pParent; while ( pWork ) { pWork->ArrangeChilds_Impl(); pWork = pWork->GetParent_Impl(); } ArrangeChilds_Impl( FALSE ); pWork = pParent; while ( pWork ) { pWork->ShowChilds_Impl(); pWork = pWork->GetParent_Impl(); } ShowChilds_Impl(); } ShowChilds_Impl(); } Reference< ::com::sun::star::task::XStatusIndicator > SfxWorkWindow::GetStatusIndicator() { Reference< com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY ); Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator; if ( xPropSet.is() ) { Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); aValue >>= xLayoutManager; if ( xLayoutManager.is() ) { xLayoutManager->createElement( m_aProgressBarResName ); xLayoutManager->showElement( m_aProgressBarResName ); Reference< ::com::sun::star::ui::XUIElement > xProgressBar = xLayoutManager->getElement( m_aProgressBarResName ); if ( xProgressBar.is() ) { xStatusIndicator = Reference< ::com::sun::star::task::XStatusIndicator >( xProgressBar->getRealInterface(), UNO_QUERY ); } } } return xStatusIndicator; } //------------------------------------------------------------------------ sal_Bool SfxWorkWindow::IsPluginMode( SfxObjectShell* pObjShell ) { if ( pObjShell && pObjShell->GetMedium() ) { SFX_ITEMSET_ARG( pObjShell->GetMedium()->GetItemSet(), pViewOnlyItem, SfxBoolItem, SID_VIEWONLY, sal_False ); if ( pViewOnlyItem && pViewOnlyItem->GetValue() ) return sal_True; } return sal_False; } //------------------------------------------------------------------------ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SfxWorkWindow::GetFrameInterface() { ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame; SfxDispatcher* pDispatcher( GetBindings().GetDispatcher() ); if ( pDispatcher ) { SfxViewFrame* pFrame = pDispatcher->GetFrame(); if ( pFrame ) xFrame = pFrame->GetFrame().GetFrameInterface(); } return xFrame; } //------------------------------------------------------------------------ void SfxWorkWindow::UpdateObjectBars_Impl() { // SplitWindows locken (d.h. Resize-Reaktion an den // DockingWindows unterdr"ucken) USHORT n; for ( n=0; nGetWindowCount()) p->Lock(); } // was man so "ofters braucht, merkt man sich (spart Code und Laufzeit) SFX_APP(); Reference< com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY ); Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; if ( xPropSet.is() ) { Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); aValue >>= xLayoutManager; } if ( !xLayoutManager.is() ) return; sal_Bool bPluginMode( sal_False ); SfxDispatcher* pDispatcher( GetBindings().GetDispatcher() ); if ( pDispatcher ) { SfxViewFrame* pFrame = pDispatcher->GetFrame(); if ( pFrame ) bPluginMode = IsPluginMode( pFrame->GetObjectShell() ); } // "uber alle Toolboxen iterieren xLayoutManager->lock(); for ( n = 0; n < aObjBarList.size(); ++n ) { USHORT nId = aObjBarList[n].nId; sal_Bool bDestroy = aObjBarList[n].bDestroy; // die Modi bestimmen, f"ur die die ToolBox gilt USHORT nTbxMode = aObjBarList[n].nMode; FASTBOOL bFullScreenTbx = SFX_VISIBILITY_FULLSCREEN == ( nTbxMode & SFX_VISIBILITY_FULLSCREEN ); nTbxMode &= ~SFX_VISIBILITY_FULLSCREEN; nTbxMode &= ~SFX_VISIBILITY_VIEWER; // wird in diesem Kontext eine ToolBox gefordert? FASTBOOL bModesMatching = ( nUpdateMode && ( nTbxMode & nUpdateMode) == nUpdateMode ); if ( bDestroy ) { rtl::OUString aTbxId( m_aTbxTypeName ); aTbxId += GetResourceURLFromResId( aObjBarList[n].nId ); xLayoutManager->destroyElement( aTbxId ); } else if ( nId != 0 && ( ( bModesMatching && !bIsFullScreen ) || ( bIsFullScreen && bFullScreenTbx ) ) ) { rtl::OUString aTbxId( m_aTbxTypeName ); aTbxId += GetResourceURLFromResId( aObjBarList[n].nId ); if ( !IsDockingAllowed() && !xLayoutManager->isElementFloating( aTbxId )) xLayoutManager->destroyElement( aTbxId ); else { xLayoutManager->requestElement( aTbxId ); if ( bPluginMode ) xLayoutManager->lockWindow( aTbxId ); } } else if ( nId != 0 ) { // ggf. Toolbox an dieser Position l"oschen rtl::OUString aTbxId( m_aTbxTypeName ); aTbxId += GetResourceURLFromResId( aObjBarList[n].nId ); xLayoutManager->destroyElement( aTbxId ); } } UpdateStatusBar_Impl(); // unlocking automatically forces Layout xLayoutManager->unlock(); UpdateChildWindows_Impl(); // SplitWindows wieder ent-locken for ( n=0; nGetWindowCount()) p->Lock(FALSE); } } bool SfxWorkWindow::AllowChildWindowCreation_Impl( const SfxChildWin_Impl& i_rCW ) const { // or checking the availability of child windows, we need access to the module const SfxViewFrame* pViewFrame = pBindings->GetDispatcher_Impl()->GetFrame(); const SfxObjectShell* pShell = pViewFrame ? pViewFrame->GetObjectShell() : NULL; const SfxModule* pModule = pShell ? pShell->GetModule() : NULL; ENSURE_OR_RETURN( pModule, "SfxWorkWindow::UpdateChildWindows_Impl: did not find an SfxModule to ask for the child win availability!", true ); return pModule->IsChildWindowAvailable( i_rCW.nId, pViewFrame ); } void SfxWorkWindow::UpdateChildWindows_Impl() { // alle vorhandenen oder in den Kontext gekommenen ChildWindows for ( USHORT n=0; nCount(); n++ ) { SfxChildWin_Impl *pCW = (*pChildWins)[n]; SfxChildWindow *pChildWin = pCW->pWin; BOOL bCreate = FALSE; if ( pCW->nId && !pCW->bDisabled && (pCW->aInfo.nFlags & SFX_CHILDWIN_ALWAYSAVAILABLE || IsVisible_Impl( pCW->nVisibility ) ) ) { // Im Kontext ist ein geeignetes ChildWindow erlaubt; // ist es auch eingeschaltet ? if ( pChildWin == NULL && pCW->bCreate ) { // Internal docking is only used for embedding into another // container. We force the floating state of all floatable // child windows. if ( !bInternalDockingAllowed ) { // Special case for all non-floatable child windows. We have // to prevent the creation here! bCreate = !( pCW->aInfo.nFlags & SFX_CHILDWIN_FORCEDOCK ); } else if ( !IsDockingAllowed() || bIsFullScreen ) // || !bInternalDocking ) { // im PresentationMode oder FullScreen nur FloatingWindows SfxChildAlignment eAlign; if ( pCW->aInfo.GetExtraData_Impl( &eAlign ) ) bCreate = ( eAlign == SFX_ALIGN_NOALIGNMENT ); } else bCreate = TRUE; if ( bCreate ) bCreate = AllowChildWindowCreation_Impl( *pCW ); // Momentan kein Fenster da, aber es ist eingeschaltet; Fenster // und ggf. Context erzeugen if ( bCreate ) CreateChildWin_Impl( pCW, FALSE ); if ( !bAllChildsVisible ) { if ( pCW->pCli ) pCW->pCli->nVisible &= ~CHILD_ACTIVE; } } else if ( pChildWin ) { // Fenster existiert schon; soll es auch sichtbar sein ? if ( ( !bIsFullScreen || pChildWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT ) && bAllChildsVisible ) { // Updatemode ist kompatibel; auf jeden Fall wieder einschalten bCreate = AllowChildWindowCreation_Impl( *pCW ); if ( bCreate ) { if ( pCW->pCli ) { // Fenster ist direktes Child if ( bAllChildsVisible && ( (IsDockingAllowed() && bInternalDockingAllowed) || pCW->pCli->eAlign == SFX_ALIGN_NOALIGNMENT ) ) pCW->pCli->nVisible |= CHILD_NOT_HIDDEN; } else { if ( pCW->bCreate && IsDockingAllowed() && bInternalDockingAllowed ) // Fenster liegt in einem SplitWindow ((SfxDockingWindow*)pChildWin->GetWindow())->Reappear_Impl(); } if ( pCW->nInterfaceId != pChildWin->GetContextId() ) pChildWin->CreateContext( pCW->nInterfaceId, GetBindings() ); } } } } if ( pChildWin && !bCreate ) { if ( !pChildWin->QueryClose() || pChildWin->IsHideNotDelete() || Application::IsUICaptured() ) { if ( pCW->pCli ) { if ( pCW->pCli->nVisible & CHILD_NOT_HIDDEN ) pCW->pCli->nVisible ^= CHILD_NOT_HIDDEN; } else ((SfxDockingWindow*)pChildWin->GetWindow())->Disappear_Impl(); } else RemoveChildWin_Impl( pCW ); } } } void SfxWorkWindow::CreateChildWin_Impl( SfxChildWin_Impl *pCW, BOOL bSetFocus ) { if ( pCW->aInfo.bVisible != 42 ) pCW->aInfo.bVisible = TRUE; SfxChildWindow *pChildWin = SfxChildWindow::CreateChildWindow( pCW->nId, pWorkWin, &GetBindings(), pCW->aInfo); if (pChildWin) { if ( bSetFocus ) bSetFocus = pChildWin->WantsFocus(); pChildWin->SetWorkWindow_Impl( this ); #if 0 // Enable-Status richtig setzen pChildWin->GetWindow()->EnableInput( pCW->bEnable && ( pWorkWin->IsInputEnabled() /* || pChildWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT */ ) ); #endif // Zumindest der ExtraString wird beim Auswerten ver"andert, also neu holen SfxChildWinInfo aInfo = pChildWin->GetInfo(); pCW->aInfo.aExtraString = aInfo.aExtraString; pCW->aInfo.bVisible = aInfo.bVisible; pCW->aInfo.nFlags |= aInfo.nFlags; // Nein !! Sonst kann man keine Fenster defaultmaessig ausschalten ( Partwindow! ) // pCW->aInfo.bVisible = TRUE; // Erzeugung war erfolgreich GetBindings().Invalidate(pCW->nId); USHORT nPos = pChildWin->GetPosition(); if (nPos != CHILDWIN_NOPOS) { DBG_ASSERT(nPos < SFX_OBJECTBAR_MAX, "Illegal objectbar position!"); if ((*pChilds)[TbxMatch(nPos)])// && // pChildWin->GetAlignment() == (*pChilds)[nPos]->eAlign ) { // ChildWindow ersetzt ObjectBar (*pChilds)[TbxMatch(nPos)]->nVisible ^= CHILD_NOT_HIDDEN; } } // make childwin keyboard accessible pWorkWin->GetSystemWindow()->GetTaskPaneList()->AddWindow( pChildWin->GetWindow() ); pCW->pWin = pChildWin; if ( pChildWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT || pChildWin->GetWindow()->GetParent() == pWorkWin) { // Das Fenster ist entweder nicht angedockt oder au\serhalb // eines SplitWindows angedockt und mu\s daher explizit als // Child registriert werden pCW->pCli = RegisterChild_Impl(*(pChildWin->GetWindow()), pChildWin->GetAlignment(), pChildWin->CanGetFocus()); pCW->pCli->nVisible = CHILD_VISIBLE; if ( pChildWin->GetAlignment() != SFX_ALIGN_NOALIGNMENT && bIsFullScreen ) pCW->pCli->nVisible ^= CHILD_ACTIVE; pCW->pCli->bSetFocus = bSetFocus; } else { // Ein angedocktes Fenster, dessen Parent nicht das WorkWindow ist, // mu\s in einem SplitWindow liegen und daher nicht explizit // registriert werden. // Das passiert aber schon bei der Initialisierung des // SfxDockingWindows! } if ( pCW->nInterfaceId != pChildWin->GetContextId() ) pChildWin->CreateContext( pCW->nInterfaceId, GetBindings() ); // Information in der INI-Datei sichern SaveStatus_Impl(pChildWin, pCW->aInfo); } } void SfxWorkWindow::RemoveChildWin_Impl( SfxChildWin_Impl *pCW ) { USHORT nId = pCW->nSaveId; SfxChildWindow *pChildWin = pCW->pWin; // vorhandenes Fenster geht aus dem Kontext und wird daher entfernt USHORT nPos = pChildWin->GetPosition(); if (nPos != CHILDWIN_NOPOS) { /* // ChildWindow "uberlagert einen ObjectBar DBG_ASSERT(nPos < SFX_OBJECTBAR_MAX, "Illegal objectbar position!"); if ((*pChilds)[TbxMatch(nPos)] && (aObjBars[nPos].nMode & nUpdateMode) ) //&& // pChildWin->GetAlignment() == (*pChilds)[nPos]->eAlign ) { // ObjectBar war "uberlagert; jetzt wieder anzeigen (*pChilds)[TbxMatch(nPos)]->nVisible ^= CHILD_NOT_HIDDEN; } */ } // Information in der INI-Datei sichern USHORT nFlags = pCW->aInfo.nFlags; pCW->aInfo = pChildWin->GetInfo(); pCW->aInfo.nFlags |= nFlags; SaveStatus_Impl(pChildWin, pCW->aInfo); pChildWin->Hide(); if ( pCW->pCli ) { // ChildWindow ist ein direktes ChildWindow und mu\s sich daher // beim WorkWindow abmelden pCW->pCli = 0; ReleaseChild_Impl(*pChildWin->GetWindow()); } else { // ChildWindow liegt in einem SplitWindow und meldet sich // selbst im dtor dort ab } pWorkWin->GetSystemWindow()->GetTaskPaneList()->RemoveWindow( pChildWin->GetWindow() ); pCW->pWin = 0; pChildWin->Destroy(); GetBindings().Invalidate( nId ); } void SfxWorkWindow::ResetStatusBar_Impl() { aStatBar.nId = 0; } //-------------------------------------------------------------------- void SfxWorkWindow::SetStatusBar_Impl( sal_uInt32 nResId, SfxShell*, SfxBindings& ) { if ( nResId && bShowStatusBar && IsVisible_Impl() ) aStatBar.nId = sal::static_int_cast(nResId); } #define SFX_ITEMTYPE_STATBAR 4 void SfxWorkWindow::SetTempStatusBar_Impl( BOOL bSet ) { if ( aStatBar.bTemp != bSet && bShowStatusBar && IsVisible_Impl() ) { BOOL bOn = FALSE; BOOL bReset = FALSE; if ( bSet && !aStatBar.nId ) { bReset = TRUE; SetStatusBar_Impl( SFX_ITEMTYPE_STATBAR, SFX_APP(), GetBindings() ); } if ( aStatBar.nId && aStatBar.bOn && !bIsFullScreen ) bOn = TRUE; aStatBar.bTemp = bSet; if ( !bOn || bReset || (!bSet && aStatBar.nId ) ) { // Nur was tun, wenn die Temp-Einstellung wirklich was bewirkt UpdateStatusBar_Impl(); ArrangeChilds_Impl(); ShowChilds_Impl(); } if ( bReset ) ResetStatusBar_Impl(); } } void SfxWorkWindow::UpdateStatusBar_Impl() { Reference< ::com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY ); Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; Any aValue = xPropSet->getPropertyValue( m_aLayoutManagerPropName ); aValue >>= xLayoutManager; // keine Statusleiste, wenn keine Id gew"unscht oder bei FullScreenView // oder wenn ausgeschaltet if ( aStatBar.nId && IsDockingAllowed() && bInternalDockingAllowed && bShowStatusBar && ( (aStatBar.bOn && !bIsFullScreen) || aStatBar.bTemp ) ) { // Id hat sich ge"andert, also passenden Statusbarmanager erzeugen, // dieser "ubernimmt die aktuelle Statusleiste; if ( xLayoutManager.is() ) xLayoutManager->requestElement( m_aStatusBarResName ); } else { // Aktuelle StatusBar vernichten // Der Manager erzeugt die Statusleiste nur, er zerst"ort sie // nicht ! if ( xLayoutManager.is() ) xLayoutManager->destroyElement( m_aStatusBarResName ); } } //------------------------------------------------------------------------ /* void SfxWorkWindow::SetObjectBarVisibility_Impl( USHORT nMask ) { switch( nMask ) { case SFX_VISIBILITY_UNVISIBLE: case SFX_VISIBILITY_STANDARD: case SFX_VISIBILITY_CLIENT: case SFX_VISIBILITY_SERVER: nOrigMode = nMask; } if (nMask != nUpdateMode) nUpdateMode = nMask; }*/ void SfxWorkWindow::MakeVisible_Impl( BOOL bVis ) { if ( bVis ) nOrigMode = SFX_VISIBILITY_STANDARD; else nOrigMode = SFX_VISIBILITY_UNVISIBLE; if ( nOrigMode != nUpdateMode) nUpdateMode = nOrigMode; } BOOL SfxWorkWindow::IsVisible_Impl() { return nOrigMode != SFX_VISIBILITY_UNVISIBLE; } //------------------------------------------------------------------------ void SfxWorkWindow::HidePopups_Impl(BOOL bHide, BOOL bParent, USHORT nId ) { for ( USHORT n = 0; n < pChildWins->Count(); ++n ) { SfxChildWindow *pCW = (*pChildWins)[n]->pWin; if (pCW && pCW->GetAlignment() == SFX_ALIGN_NOALIGNMENT && pCW->GetType() != nId) { Window *pWin = pCW->GetWindow(); SfxChild_Impl *pChild = FindChild_Impl(*pWin); if (bHide) { pChild->nVisible &= ~CHILD_ACTIVE; pCW->Hide(); } else { pChild->nVisible |= CHILD_ACTIVE; if ( CHILD_VISIBLE == (pChild->nVisible & CHILD_VISIBLE) ) pCW->Show( SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); } } } if ( bParent && pParent ) pParent->HidePopups_Impl( bHide, bParent, nId ); } //------------------------------------------------------------------------ void SfxWorkWindow::ConfigChild_Impl(SfxChildIdentifier eChild, SfxDockingConfig eConfig, USHORT nId) { SfxDockingWindow* pDockWin=0; USHORT nPos = USHRT_MAX; Window *pWin=0; SfxChildWin_Impl *pCW = 0; if ( eChild == SFX_CHILDWIN_OBJECTBAR ) { return; } else { // configure direct childwindow for (USHORT n=0; nCount(); n++) { pCW = (*pChildWins)[n]; SfxChildWindow *pChild = pCW->pWin; if ( pChild ) { if ( pChild->GetType() == nId ) { if ( pChild->GetWindow()->GetType() == RSC_DOCKINGWINDOW ) // it's a DockingWindow pDockWin = (SfxDockingWindow*) pChild->GetWindow(); else // FloatingWindow or ModelessDialog pWin = pChild->GetWindow(); break; } } } if ( pDockWin ) { if ( eChild == SFX_CHILDWIN_DOCKINGWINDOW || pDockWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT ) { if ( eChild == SFX_CHILDWIN_SPLITWINDOW && eConfig == SFX_TOGGLEFLOATMODE) { // DockingWindow was dragged out of a SplitWindow pCW->pCli = RegisterChild_Impl(*pDockWin, pDockWin->GetAlignment(), pCW->pWin->CanGetFocus()); pCW->pCli->nVisible = CHILD_VISIBLE; } pWin = pDockWin; } else { SfxSplitWindow *pSplitWin = GetSplitWindow_Impl(pDockWin->GetAlignment()); // configure DockingWindow inside a SplitWindow if ( eConfig == SFX_TOGGLEFLOATMODE) { // DockingWindow was dragged into a SplitWindow pCW->pCli = 0; ReleaseChild_Impl(*pDockWin); } pWin = pSplitWin->GetSplitWindow(); if ( pSplitWin->GetWindowCount() == 1 ) ((SplitWindow*)pWin)->Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); } } DBG_ASSERT( pCW, "Unknown window!" ); if ( !pCW && pParent ) { pParent->ConfigChild_Impl( eChild, eConfig, nId ); return; } } if ( !bSorted ) // windows may have been registered and released without an update until now Sort_Impl(); SfxChild_Impl *pChild = 0; USHORT n; for ( n=0; npWin == pWin ) break; } if ( n < aSortedList.Count() ) // sometimes called while toggeling float mode nPos = aSortedList[n]; switch ( eConfig ) { case SFX_SETDOCKINGRECTS : { if ( nPos == USHRT_MAX ) return; // SfxChild_Impl *pChild = (*pChilds)[nPos]; Rectangle aOuterRect( GetTopRect_Impl() ); aOuterRect.SetPos( pWorkWin->OutputToScreenPixel( aOuterRect.TopLeft() )); Rectangle aInnerRect( aOuterRect ); BOOL bTbx = (eChild == SFX_CHILDWIN_OBJECTBAR); // Das gerade betroffene Fenster wird bei der Berechnung des // inneren Rechtecks mit eingeschlossen! for ( USHORT m=0; mnVisible == CHILD_VISIBLE && pCli->pWin ) { switch ( pCli->eAlign ) { case SFX_ALIGN_TOP: // Objekt-Toolboxen kommen immer zuletzt //if ( bTbx || i <= nPos) aInnerRect.Top() += pCli->aSize.Height(); break; case SFX_ALIGN_TOOLBOXTOP: // Toolbox geht nur vor, wenn nicht h"ohere Position if ( bTbx && i <= nPos) aInnerRect.Top() += pCli->aSize.Height(); break; case SFX_ALIGN_HIGHESTTOP: // Geht immer vor aInnerRect.Top() += pCli->aSize.Height(); break; case SFX_ALIGN_LOWESTTOP: // Wird nur mitgez"ahlt, wenn es das aktuelle Fenster ist if ( i == nPos ) aInnerRect.Top() += pCli->aSize.Height(); break; case SFX_ALIGN_BOTTOM: // Objekt-Toolboxen kommen immer zuletzt //if ( bTbx || i <= nPos) aInnerRect.Bottom() -= pCli->aSize.Height(); break; case SFX_ALIGN_TOOLBOXBOTTOM: // Toolbox geht nur vor, wenn nicht h"ohere Position if ( bTbx && i <= nPos) aInnerRect.Bottom() -= pCli->aSize.Height(); break; case SFX_ALIGN_LOWESTBOTTOM: // Geht immer vor aInnerRect.Bottom() -= pCli->aSize.Height(); break; case SFX_ALIGN_HIGHESTBOTTOM: // Wird nur mitgez"ahlt, wenn es das aktuelle Fenster ist if ( i == nPos ) aInnerRect.Bottom() -= pCli->aSize.Height(); break; case SFX_ALIGN_LEFT: // Toolboxen kommen immer zuletzt //if (bTbx || i <= nPos) aInnerRect.Left() += pCli->aSize.Width(); break; case SFX_ALIGN_TOOLBOXLEFT: // Toolboxen kommen immer zuletzt if (bTbx && i <= nPos) aInnerRect.Left() += pCli->aSize.Width(); break; case SFX_ALIGN_FIRSTLEFT: // Geht immer vor aInnerRect.Left() += pCli->aSize.Width(); break; case SFX_ALIGN_LASTLEFT: // Wird nur mitgez"ahlt, wenn es das aktuelle Fenster ist if (i == nPos) aInnerRect.Left() += pCli->aSize.Width(); case SFX_ALIGN_RIGHT: // Toolboxen kommen immer zuletzt //if (bTbx || i <= nPos) aInnerRect.Right() -= pCli->aSize.Width(); break; case SFX_ALIGN_TOOLBOXRIGHT: // Toolboxen kommen immer zuletzt if (bTbx && i <= nPos) aInnerRect.Right() -= pCli->aSize.Width(); break; case SFX_ALIGN_FIRSTRIGHT: // Wird nur mitgez"ahlt, wenn es das aktuelle Fenster ist if (i == nPos) aInnerRect.Right() -= pCli->aSize.Width(); break; case SFX_ALIGN_LASTRIGHT: // Geht immer vor aInnerRect.Right() -= pCli->aSize.Width(); break; default: break; } } } pDockWin->SetDockingRects(aOuterRect, aInnerRect); break; } case SFX_MOVEDOCKINGWINDOW : case SFX_ALIGNDOCKINGWINDOW : case SFX_TOGGLEFLOATMODE: { if ( nPos == USHRT_MAX && !pCW ) return; SfxChildAlignment eAlign = SFX_ALIGN_NOALIGNMENT; SfxChild_Impl *pCli = ( nPos != USHRT_MAX ) ? (*pChilds)[nPos] : 0; if ( pCli && pDockWin ) { eAlign = pDockWin->GetAlignment(); if ( eChild == SFX_CHILDWIN_DOCKINGWINDOW || eAlign == SFX_ALIGN_NOALIGNMENT) { // configuration inside the SplitWindow, no change for the SplitWindows' configuration pCli->bResize = TRUE; pCli->aSize = pDockWin->GetSizePixel(); } } if ( pCli ) { if( pCli->eAlign != eAlign ) { bSorted = FALSE; pCli->eAlign = eAlign; } ArrangeChilds_Impl(); ShowChilds_Impl(); } if ( pCW && pCW->pWin ) { // store changed configuration USHORT nFlags = pCW->aInfo.nFlags; pCW->aInfo = pCW->pWin->GetInfo(); pCW->aInfo.nFlags |= nFlags; if ( eConfig != SFX_MOVEDOCKINGWINDOW ) SaveStatus_Impl( pCW->pWin, pCW->aInfo); } break; } } } //-------------------------------------------------------------------- void SfxWorkWindow::SetChildWindowVisible_Impl( sal_uInt32 lId, BOOL bEnabled, USHORT nMode ) { USHORT nInter = (USHORT) ( lId >> 16 ); USHORT nId = (USHORT) ( lId & 0xFFFF ); SfxChildWin_Impl *pCW=NULL; SfxWorkWindow *pWork = pParent; // Den obersten parent nehmen; ChildWindows werden immer am WorkWindow // der Task bzw. des Frames oder am AppWorkWindow angemeldet while ( pWork && pWork->pParent ) pWork = pWork->pParent; if ( pWork ) { // Dem Parent schon bekannt ? USHORT nCount = pWork->pChildWins->Count(); for (USHORT n=0; npChildWins)[n]->nSaveId == nId) { pCW = (*pWork->pChildWins)[n]; break; } } if ( !pCW ) { // Kein Parent oder dem Parent noch unbekannt, dann bei mir suchen USHORT nCount = pChildWins->Count(); for (USHORT n=0; nnSaveId == nId) { pCW = (*pChildWins)[n]; break; } } if ( !pCW ) { // Ist neu, also initialisieren; je nach Flag beim Parent oder bei // mir eintragen pCW = new SfxChildWin_Impl( lId ); pCW->nId = nId; InitializeChild_Impl( pCW ); if ( pWork && !( pCW->aInfo.nFlags & SFX_CHILDWIN_TASK ) ) pWork->pChildWins->Insert( pWork->pChildWins->Count(), pCW ); else pChildWins->Insert( pChildWins->Count(), pCW ); } pCW->nId = nId; if ( nInter ) pCW->nInterfaceId = nInter; pCW->nVisibility = nMode; pCW->bEnable = bEnabled; #if 0 if ( pCW->pWin ) pCW->pWin->GetWindow()->EnableInput( bEnabled && ( pWorkWin->IsInputEnabled() /* || pCW->pWin->GetAlignment() == SFX_ALIGN_NOALIGNMENT */ ) ); #endif pCW->nVisibility = nMode; } //-------------------------------------------------------------------- // Der An/Aus-Status eines ChildWindows wird umgeschaltet. void SfxWorkWindow::ToggleChildWindow_Impl(USHORT nId, BOOL bSetFocus) { USHORT nCount = pChildWins->Count(); USHORT n; for (n=0; nnId == nId) break; if ( npWin; bool bCreationAllowed( true ); if ( !bInternalDockingAllowed ) { // Special case for all non-floatable child windows. We have // to prevent the creation here! bCreationAllowed = !( pCW->aInfo.nFlags & SFX_CHILDWIN_FORCEDOCK ); } if ( bCreationAllowed ) { if ( pCW->bCreate ) { if ( pChild ) { if ( pChild->QueryClose() ) { pCW->bCreate = FALSE; if ( pChild->IsHideAtToggle() ) { ShowChildWindow_Impl( nId, FALSE, bSetFocus ); } else { // Fenster soll ausgeschaltet werdem pChild->SetVisible_Impl( FALSE ); RemoveChildWin_Impl( pCW ); } } } else { // no actual Window exists, yet => just remember the "switched off" state pCW->bCreate = FALSE; } } else { pCW->bCreate = AllowChildWindowCreation_Impl( *pCW ); if ( pCW->bCreate ) { if ( pChild ) { ShowChildWindow_Impl( nId, TRUE, bSetFocus ); } else { // create actual Window CreateChildWin_Impl( pCW, bSetFocus ); if ( !pCW->pWin ) // no success pCW->bCreate = FALSE; } } } } ArrangeChilds_Impl(); ShowChilds_Impl(); if ( pCW->bCreate && bCreationAllowed ) { if ( !pCW->pCli ) { SfxDockingWindow *pDock = (SfxDockingWindow*) pCW->pWin->GetWindow(); if ( pDock->IsAutoHide_Impl() ) pDock->AutoShow_Impl(); } } return; } else if ( pParent ) { pParent->ToggleChildWindow_Impl( nId, bSetFocus ); return; } #ifdef DBG_UTIL nCount = pChildWins->Count(); for (n=0; nnSaveId == nId) break; if ( n < nCount ) { DBG_ERROR("ChildWindow ist nicht im Kontext!"); } else { DBG_ERROR("ChildWindow ist nicht registriert!"); } #endif } //-------------------------------------------------------------------- BOOL SfxWorkWindow::HasChildWindow_Impl(USHORT nId) { USHORT nCount = pChildWins->Count(); USHORT n; for (n=0; nnSaveId == nId) break; if (npWin; return ( pChild && pCW->bCreate ); } if ( pParent ) return pParent->HasChildWindow_Impl( nId ); return FALSE; } BOOL SfxWorkWindow::IsFloating( USHORT nId ) { SfxChildWin_Impl *pCW=NULL; SfxWorkWindow *pWork = pParent; // Den obersten parent nehmen; ChildWindows werden immer am WorkWindow // der Task bzw. des Frames oder am AppWorkWindow angemeldet while ( pWork && pWork->pParent ) pWork = pWork->pParent; if ( pWork ) { // Dem Parent schon bekannt ? USHORT nCount = pWork->pChildWins->Count(); for (USHORT n=0; npChildWins)[n]->nSaveId == nId) { pCW = (*pWork->pChildWins)[n]; break; } } if ( !pCW ) { // Kein Parent oder dem Parent noch unbekannt, dann bei mir suchen USHORT nCount = pChildWins->Count(); for (USHORT n=0; nnSaveId == nId) { pCW = (*pChildWins)[n]; break; } } if ( !pCW ) { // Ist neu, also initialisieren; je nach Flag beim Parent oder bei // mir eintragen pCW = new SfxChildWin_Impl( nId ); pCW->bEnable = FALSE; pCW->nId = 0; pCW->nVisibility = 0; InitializeChild_Impl( pCW ); if ( pWork && !( pCW->aInfo.nFlags & SFX_CHILDWIN_TASK ) ) pWork->pChildWins->Insert( pWork->pChildWins->Count(), pCW ); else pChildWins->Insert( pChildWins->Count(), pCW ); } SfxChildAlignment eAlign; if ( pCW->aInfo.GetExtraData_Impl( &eAlign ) ) return( eAlign == SFX_ALIGN_NOALIGNMENT ); else return TRUE; } //-------------------------------------------------------------------- BOOL SfxWorkWindow::KnowsChildWindow_Impl(USHORT nId) { SfxChildWin_Impl *pCW=0; USHORT nCount = pChildWins->Count(); USHORT n; for (n=0; nnSaveId == nId) break; } if (naInfo.nFlags & SFX_CHILDWIN_ALWAYSAVAILABLE) && !IsVisible_Impl( pCW->nVisibility ) ) return FALSE; return pCW->bEnable; } else if ( pParent ) return pParent->KnowsChildWindow_Impl( nId ); else return FALSE; } //-------------------------------------------------------------------- void SfxWorkWindow::SetChildWindow_Impl(USHORT nId, BOOL bOn, BOOL bSetFocus) { SfxChildWin_Impl *pCW=NULL; SfxWorkWindow *pWork = pParent; // Den obersten parent nehmen; ChildWindows werden immer am WorkWindow // der Task bzw. des Frames oder am AppWorkWindow angemeldet while ( pWork && pWork->pParent ) pWork = pWork->pParent; if ( pWork ) { // Dem Parent schon bekannt ? USHORT nCount = pWork->pChildWins->Count(); for (USHORT n=0; npChildWins)[n]->nSaveId == nId) { pCW = (*pWork->pChildWins)[n]; break; } } if ( !pCW ) { // Kein Parent oder dem Parent noch unbekannt, dann bei mir suchen USHORT nCount = pChildWins->Count(); for (USHORT n=0; nnSaveId == nId) { pCW = (*pChildWins)[n]; pWork = this; break; } } if ( !pCW ) { // Ist neu, also initialisieren; je nach Flag beim Parent oder bei // mir eintragen pCW = new SfxChildWin_Impl( nId ); InitializeChild_Impl( pCW ); if ( !pWork || pCW->aInfo.nFlags & SFX_CHILDWIN_TASK ) pWork = this; pWork->pChildWins->Insert( pWork->pChildWins->Count(), pCW ); } if ( pCW->bCreate != bOn ) pWork->ToggleChildWindow_Impl(nId,bSetFocus); } //-------------------------------------------------------------------- void SfxWorkWindow::ShowChildWindow_Impl(USHORT nId, BOOL bVisible, BOOL bSetFocus) { USHORT nCount = pChildWins->Count(); SfxChildWin_Impl* pCW=0; USHORT n; for (n=0; nnId == nId) break; } if ( npWin; if ( pChildWin ) { if ( bVisible ) { if ( pCW->pCli ) { pCW->pCli->bSetFocus = bSetFocus; pCW->pCli->nVisible = CHILD_VISIBLE; pChildWin->Show( bSetFocus && pChildWin->WantsFocus() ? 0 : SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); } else ((SfxDockingWindow*)pChildWin->GetWindow())->Reappear_Impl(); } else { if ( pCW->pCli ) { pCW->pCli->nVisible = CHILD_VISIBLE ^ CHILD_NOT_HIDDEN; pCW->pWin->Hide(); } else ((SfxDockingWindow*)pChildWin->GetWindow())->Disappear_Impl(); } ArrangeChilds_Impl(); ShowChilds_Impl(); } else if ( bVisible ) { SetChildWindow_Impl( nId, TRUE, bSetFocus ); pChildWin = pCW->pWin; } if ( pChildWin ) { pChildWin->SetVisible_Impl( bVisible ); USHORT nFlags = pCW->aInfo.nFlags; pCW->aInfo = pChildWin->GetInfo(); pCW->aInfo.nFlags |= nFlags; if ( !pCW->bCreate ) SaveStatus_Impl( pChildWin, pCW->aInfo ); } return; } if ( pParent ) { pParent->ShowChildWindow_Impl( nId, bVisible, bSetFocus ); return; } #ifdef DBG_UTIL nCount = pChildWins->Count(); for (n=0; nnSaveId == nId) break; if ( nCount(); USHORT n; for (n=0; nnSaveId == nId) break; if (npWin; else if ( pParent ) return pParent->GetChildWindow_Impl( nId ); return 0; } //------------------------------------------------------------------------ void SfxWorkWindow::ResetChildWindows_Impl() { // if ( pParent ) // pParent->ResetChildWindows_Impl(); for ( USHORT n = 0; n < pChildWins->Count(); ++n ) { (*pChildWins)[n]->nId = 0; (*pChildWins)[n]->bEnable = FALSE; } } //------------------------------------------------------------------------ // Virtuelle Methode, die die Gr"o\se der Fl"ache (client area) des parent // windows liefert, in der Child-Fenster angeordnet werden k"onnen. // in der ClientArea des parent findet. Rectangle SfxWorkWindow::GetTopRect_Impl() { return Rectangle (Point(), pWorkWin->GetOutputSizePixel() ); } //------------------------------------------------------------------------ // Virtuelle Methode, die die Gr"o\se der Fl"ache (client area) des parent // windows liefert, in der Child-Fenster angeordnet werden k"onnen. // in der ClientArea des parent findet. Rectangle SfxFrameWorkWin_Impl::GetTopRect_Impl() { return pMasterFrame->GetTopOuterRectPixel_Impl(); } //------------------------------------------------------------------------ // Virtuelle Methode, um herauszufinden, ob ein Child-Fenster noch Platz // in der ClientArea des parent findet. BOOL SfxWorkWindow::RequestTopToolSpacePixel_Impl( SvBorder aBorder ) { if ( !IsDockingAllowed() || aClientArea.GetWidth() < aBorder.Left() + aBorder.Right() || aClientArea.GetHeight() < aBorder.Top() + aBorder.Bottom() ) return FALSE; else return TRUE;; } void SfxWorkWindow::SaveStatus_Impl(SfxChildWindow *pChild, const SfxChildWinInfo &rInfo) { // Den Status vom Presentation mode wollen wir nicht sichern if ( IsDockingAllowed() && bInternalDockingAllowed ) pChild->SaveStatus(rInfo); } void SfxWorkWindow::InitializeChild_Impl(SfxChildWin_Impl *pCW) { SfxChildWinFactory* pFact=0; SfxApplication *pApp = SFX_APP(); { SfxChildWinFactArr_Impl &rFactories = pApp->GetChildWinFactories_Impl(); for ( USHORT nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) { pFact = rFactories[nFactory]; if ( pFact->nId == pCW->nSaveId ) { pCW->aInfo = pFact->aInfo; SfxChildWindow::InitializeChildWinFactory_Impl( pCW->nSaveId, pCW->aInfo); pCW->bCreate = pCW->aInfo.bVisible; USHORT nFlags = pFact->aInfo.nFlags; if ( nFlags & SFX_CHILDWIN_TASK ) pCW->aInfo.nFlags |= SFX_CHILDWIN_TASK; if ( nFlags & SFX_CHILDWIN_CANTGETFOCUS ) pCW->aInfo.nFlags |= SFX_CHILDWIN_CANTGETFOCUS; if ( nFlags & SFX_CHILDWIN_FORCEDOCK ) pCW->aInfo.nFlags |= SFX_CHILDWIN_FORCEDOCK; pFact->aInfo = pCW->aInfo; return; } } } SfxDispatcher *pDisp = pBindings->GetDispatcher_Impl(); SfxModule *pMod = pDisp ? SfxModule::GetActiveModule( pDisp->GetFrame() ) :0; if ( pMod ) { SfxChildWinFactArr_Impl *pFactories = pMod->GetChildWinFactories_Impl(); if ( pFactories ) { SfxChildWinFactArr_Impl &rFactories = *pFactories; for ( USHORT nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) { pFact = rFactories[nFactory]; if ( pFact->nId == pCW->nSaveId ) { pCW->aInfo = pFact->aInfo; SfxChildWindow::InitializeChildWinFactory_Impl( pCW->nSaveId, pCW->aInfo); pCW->bCreate = pCW->aInfo.bVisible; USHORT nFlags = pFact->aInfo.nFlags; if ( nFlags & SFX_CHILDWIN_TASK ) pCW->aInfo.nFlags |= SFX_CHILDWIN_TASK; if ( nFlags & SFX_CHILDWIN_CANTGETFOCUS ) pCW->aInfo.nFlags |= SFX_CHILDWIN_CANTGETFOCUS; if ( nFlags & SFX_CHILDWIN_FORCEDOCK ) pCW->aInfo.nFlags |= SFX_CHILDWIN_FORCEDOCK; if ( nFlags & SFX_CHILDWIN_ALWAYSAVAILABLE ) pCW->aInfo.nFlags |= SFX_CHILDWIN_ALWAYSAVAILABLE; pFact->aInfo = pCW->aInfo; return; } } } } } /* SfxStatBar_Impl* SfxWorkWindow::GetStatusBar_Impl() { return &aStatBar; } */ SfxSplitWindow* SfxWorkWindow::GetSplitWindow_Impl( SfxChildAlignment eAlign ) { switch ( eAlign ) { case SFX_ALIGN_TOP: return pSplit[2]; case SFX_ALIGN_BOTTOM: return pSplit[3]; case SFX_ALIGN_LEFT: return pSplit[0]; case SFX_ALIGN_RIGHT: return pSplit[1]; default: return 0; } } void SfxWorkWindow::MakeChildsVisible_Impl( BOOL bVis ) { if ( pParent ) pParent->MakeChildsVisible_Impl( bVis ); bAllChildsVisible = bVis; if ( bVis ) { if ( !bSorted ) Sort_Impl(); for ( USHORT n=0; neAlign == SFX_ALIGN_NOALIGNMENT) || (IsDockingAllowed() && bInternalDockingAllowed) ) pCli->nVisible |= CHILD_ACTIVE; } } else { if ( !bSorted ) Sort_Impl(); for ( USHORT n=0; nnVisible &= ~CHILD_ACTIVE; } } } BOOL SfxWorkWindow::IsAutoHideMode( const SfxSplitWindow *pSplitWin ) { for ( USHORT n=0; nIsAutoHide( TRUE ) ) return TRUE; } return FALSE; } void SfxWorkWindow::EndAutoShow_Impl( Point aPos ) { if ( pParent ) pParent->EndAutoShow_Impl( aPos ); for ( USHORT n=0; nIsAutoHide() ) { Point aLocalPos = p->ScreenToOutputPixel( aPos ); Point aEmptyPoint = Point(); Rectangle aRect( aEmptyPoint, p->GetSizePixel() ); if ( !aRect.IsInside( aLocalPos ) ) p->FadeOut(); } } } void SfxWorkWindow::ArrangeAutoHideWindows( SfxSplitWindow *pActSplitWin ) { if ( m_nLock ) return; if ( pParent ) pParent->ArrangeAutoHideWindows( pActSplitWin ); Rectangle aArea( aUpperClientArea ); for ( USHORT n=0; nIsFadeIn(); Window *pDummy = pSplitWin->GetSplitWindow(); Window *pWin = bDummyWindow ? pDummy : pSplitWin; if ( (pSplitWin->IsPinned() && !bDummyWindow) || (!pWin->IsVisible() && pActSplitWin != pSplitWin) ) continue; // Breite und Position des Dummy-Fensters als Ausgangspunkt Size aSize = pDummy->GetSizePixel(); Point aPos = pDummy->GetPosPixel(); switch ( n ) { case ( 0 ) : { // Linkes SplitWindow // Breite vom Fenster selbst holen, wenn nicht das DummyWindow if ( !bDummyWindow ) aSize.Width() = pSplitWin->GetSizePixel().Width(); // Wenn links ein Window sichtbar ist, beginnt der freie // Bereich rechts davon bzw. bei der Client area long nLeft = aPos.X() + aSize.Width(); if ( nLeft > aArea.Left() ) aArea.Left() = nLeft; break; } case ( 1 ) : { // Rechtes SplitWindow // Position um Differenz der Breiten korrigieren aPos.X() += aSize.Width(); // Breite vom Fenster selbst holen, wenn nicht das DummyWindow if ( !bDummyWindow ) aSize.Width() = pSplitWin->GetSizePixel().Width(); aPos.X() -= aSize.Width(); // Wenn links schon ein Fenster aufgeklappt ist, darf // das rechte nicht dar"uber gehen if ( aPos.X() < aArea.Left() ) { aPos.X() = aArea.Left(); aSize.Width() = aArea.GetWidth(); } // Wenn rechts ein Window sichtbar ist, endet der freie // Bereich links davon bzw. bei der Client area long nRight = aPos.X(); if ( nRight < aArea.Right() ) aArea.Right() = nRight; break; } case ( 2 ) : { // Oberes SplitWindow // H"ohe vom Fenster selbst holen, wenn nicht das DummyWindow if ( !bDummyWindow ) aSize.Height() = pSplitWin->GetSizePixel().Height(); // Breite anpassen, je nachdem ob links oder rechts // schon ein Fenster aufgeklappt ist aPos.X() = aArea.Left(); aSize.Width() = aArea.GetWidth(); // Wenn oben ein Window sichtbar ist, beginnt der freie // Bereich darunter bzw. bei der Client Area long nTop = aPos.Y() + aSize.Height(); if ( nTop > aArea.Top() ) aArea.Top() = nTop; break; } case ( 3 ) : { // Das untere SplitWindow // Position um Differenz der H"ohen korrigieren aPos.Y() += aSize.Height(); // H"ohe vom Fenster selbst holen, wenn nicht das DummmyWindow if ( !bDummyWindow ) aSize.Height() = pSplitWin->GetSizePixel().Height(); aPos.Y() -= aSize.Height(); // Breite anpassen, je nachdem ob links oder rechts // schon ein Fenster aufgeklappt ist aPos.X() = aArea.Left(); aSize.Width() = aArea.GetWidth(); // Wenn oben schon ein Fenster aufgeklappt ist, darf // das untere nicht dar"uber gehen if ( aPos.Y() < aArea.Top() ) { aPos.Y() = aArea.Top(); aSize.Height() = aArea.GetHeight(); } break; } } if ( !bDummyWindow ) // Das FadeIn-Window ist ein Float, dessen Koordinaten in // Screenkoordinaten gesetzt werden pSplitWin->SetPosSizePixel( pWorkWin->OutputToScreenPixel(aPos), aSize ); else // Das angedockte DummyWindow pDummy->SetPosSizePixel( aPos, aSize ); } } Rectangle SfxWorkWindow::GetFreeArea( BOOL bAutoHide ) const { if ( bAutoHide ) { Rectangle aArea( aClientArea ); for ( USHORT n=0; nIsPinned() || !pSplit[n]->IsVisible() ) continue; Size aSize = pSplit[n]->GetSizePixel(); switch ( n ) { case ( 0 ) : aArea.Left() += aSize.Width(); break; case ( 1 ) : aArea.Right() -= aSize.Width(); break; case ( 2 ) : aArea.Top() += aSize.Height(); break; case ( 3 ) : aArea.Bottom() -= aSize.Height(); break; } } return aArea; } else return aClientArea; } SfxChildWinController_Impl::SfxChildWinController_Impl( USHORT nID, SfxWorkWindow *pWork ) : SfxControllerItem( nID, pWork->GetBindings() ) , pWorkwin( pWork ) {} ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > SfxWorkWindow::CreateDispatch( const String& ) { return ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >(); } void SfxChildWinController_Impl::StateChanged( USHORT nSID, SfxItemState eState, const SfxPoolItem* ) { pWorkwin->DisableChildWindow_Impl( nSID, eState == SFX_ITEM_DISABLED ); } void SfxWorkWindow::DisableChildWindow_Impl( USHORT nId, BOOL bDisable ) { USHORT nCount = pChildWins->Count(); USHORT n; for (n=0; nnSaveId == nId) break; if ( nbDisabled != bDisable ) { (*pChildWins)[n]->bDisabled = bDisable; UpdateChildWindows_Impl(); ArrangeChilds_Impl(); ShowChilds_Impl(); } } void SfxWorkWindow::SetActiveChild_Impl( Window *pChild ) { pActiveChild = pChild; } Window* SfxWorkWindow::GetActiveChild_Impl() { return pActiveChild; } BOOL SfxWorkWindow::ActivateNextChild_Impl( BOOL bForward ) { // Alle Kinder gem"a\s Liste sortieren SvUShorts aList; for ( USHORT i=SFX_OBJECTBAR_MAX; iCount(); i++) { SfxChild_Impl *pCli = (*pChilds)[i]; if ( pCli && pCli->bCanGetFocus && pCli->pWin ) { USHORT k; for (k=0; keAlign) > ChildTravelValue(pCli->eAlign) ) break; aList.Insert(i,k); } } if ( aList.Count() == 0 ) return FALSE; USHORT nTopValue = ChildTravelValue( SFX_ALIGN_LOWESTTOP ); for ( USHORT i=0; ipWin && ChildTravelValue( pCli->eAlign ) > nTopValue ) break; } USHORT n = bForward ? 0 : aList.Count()-1; SfxChild_Impl *pAct=NULL; if ( pActiveChild ) { // Das aktive Fenster suchen for ( n=0; npWin && ( pCli->pWin == pActiveChild || !pActiveChild ) ) { pAct = pCli; break; } } } // dummy entries for the container window aList.Insert( 0xFFFF, 0 ); aList.Insert( 0xFFFF, aList.Count() ); n = n + 1; if ( pAct ) { for ( USHORT i=0; ipWin == p ) { if( p->ActivateNextChild_Impl( bForward ) ) return TRUE; break; } } // pAct ist ein direktes ChildWindow // mit dem Nachfolger bzw. Vorg"anger des aktiven Fensters weitermachen if ( bForward ) n = n+1; else n = n-1; if ( n == 0 || n == aList.Count()-1 ) return FALSE; } for( ;; ) { SfxChild_Impl* pCli = (*pChilds)[aList[n]]; if ( pCli->pWin ) { SfxChild_Impl* pNext = pCli; for ( USHORT i=0; npWin == p ) { // Das erste/letzte Fenster dort aktivieren p->SetActiveWindow_Impl( NULL ); pNext = NULL; if( p->ActivateNextChild_Impl( bForward ) ) return TRUE; break; } } if ( pNext ) { pNext->pWin->GrabFocus(); pActiveChild = pNext->pWin; return TRUE; } } if ( bForward ) n = n+1; else n = n-1; if ( n == 0 || n == aList.Count()-1 ) break; } return FALSE; } void SfxWorkWindow::SetObjectBarCustomizeMode_Impl( BOOL ) { } void SfxWorkWindow::DataChanged_Impl( const DataChangedEvent& ) { USHORT n; USHORT nCount = pChildWins->Count(); for (n=0; npWin ) pCW->pWin->GetWindow()->UpdateSettings( Application::GetSettings() ); } ArrangeChilds_Impl(); }