/************************************************************** * * 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. * *************************************************************/ #include "precompiled_sd.hxx" #include "ChildWindowPane.hxx" #include "PaneDockingWindow.hxx" #include "ViewShellBase.hxx" #include "ViewShellManager.hxx" #include "framework/FrameworkHelper.hxx" #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; namespace sd { namespace framework { ChildWindowPane::ChildWindowPane ( const Reference& rxPaneId, sal_uInt16 nChildWindowId, ViewShellBase& rViewShellBase, ::std::auto_ptr pShell) : ChildWindowPaneInterfaceBase(rxPaneId,(::Window*)NULL), mnChildWindowId(nChildWindowId), mrViewShellBase(rViewShellBase), mpShell(pShell), mbHasBeenActivated(false) { mrViewShellBase.GetViewShellManager()->ActivateShell(mpShell.get()); SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame(); if (pViewFrame != NULL) { if (mrViewShellBase.IsActive()) { if (pViewFrame->KnowsChildWindow(mnChildWindowId)) { if (pViewFrame->HasChildWindow(mnChildWindowId)) { // The ViewShellBase has already been activated. Make // the child window visible as soon as possible. pViewFrame->SetChildWindow(mnChildWindowId, sal_True); OSL_TRACE("ChildWindowPane:activating now"); } else { // The window is created asynchronously. Rely on the // ConfigurationUpdater to try another update, and with // that another request for this window, in a short // time. OSL_TRACE("ChildWindowPane:activated asynchronously"); } } else { OSL_TRACE("ChildWindowPane:not known"); } } else { // The ViewShellBase has not yet been activated. Hide the // window and wait a little before it is made visible. See // comments in the GetWindow() method for an explanation. pViewFrame->SetChildWindow(mnChildWindowId, sal_False); OSL_TRACE("ChildWindowPane:base not active"); } } } ChildWindowPane::~ChildWindowPane (void) throw() { } void ChildWindowPane::Hide (void) { SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame(); if (pViewFrame != NULL) if (pViewFrame->KnowsChildWindow(mnChildWindowId)) if (pViewFrame->HasChildWindow(mnChildWindowId)) pViewFrame->SetChildWindow(mnChildWindowId, sal_False); // Release the window because when the child window is shown again it // may use a different window. mxWindow = NULL; } void SAL_CALL ChildWindowPane::disposing (void) { ::osl::MutexGuard aGuard (maMutex); mrViewShellBase.GetViewShellManager()->DeactivateShell(mpShell.get()); mpShell.reset(); if (mxWindow.is()) { mxWindow->removeEventListener(this); } Pane::disposing(); } ::Window* ChildWindowPane::GetWindow (void) { do { if (mxWindow.is()) // Window already exists => nothing to do. break; // When the window is not yet present then obtain it only when the // shell has already been activated. The activation is not // necessary for the code to work properly but is used to optimize // the layouting and displaying of the window. When it is made // visible to early then some layouting seems to be made twice or at // an inconvenient time and the overall process of initializing the // Impress takes longer. if ( ! mbHasBeenActivated && mpShell.get()!=NULL && ! mpShell->IsActive()) break; mbHasBeenActivated = true; SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame(); if (pViewFrame == NULL) break; // The view frame has to know the child window. This can be the // case, when for example the document is in read-only mode: the // task pane is then not available. if ( ! pViewFrame->KnowsChildWindow(mnChildWindowId)) break; pViewFrame->SetChildWindow(mnChildWindowId, sal_True); SfxChildWindow* pChildWindow = pViewFrame->GetChildWindow(mnChildWindowId); if (pChildWindow == NULL) if (pViewFrame->HasChildWindow(mnChildWindowId)) { // The child window is not yet visible. Ask the view frame // to show it and try again to get access to the child // window. pViewFrame->ShowChildWindow(mnChildWindowId, sal_True); pChildWindow = pViewFrame->GetChildWindow(mnChildWindowId); } // When the child window is still not visible then we have to try later. if (pChildWindow == NULL) break; // From the child window get the docking window and from that the // content window that is the container for the actual content. PaneDockingWindow* pDockingWindow = dynamic_cast( pChildWindow->GetWindow()); if (pDockingWindow == NULL) break; // At last, we have access to the window and its UNO wrapper. mpWindow = &pDockingWindow->GetContentWindow(); mxWindow = VCLUnoHelper::GetInterface(mpWindow); // Register as window listener to be informed when the child window // is hidden. if (mxWindow.is()) mxWindow->addEventListener(this); } while (false); return mpWindow; } Reference SAL_CALL ChildWindowPane::getWindow (void) throw (RuntimeException) { if (mpWindow == NULL || ! mxWindow.is()) GetWindow(); return Pane::getWindow(); } IMPLEMENT_FORWARD_XINTERFACE2( ChildWindowPane, ChildWindowPaneInterfaceBase, Pane); IMPLEMENT_FORWARD_XTYPEPROVIDER2( ChildWindowPane, ChildWindowPaneInterfaceBase, Pane); //----- XEventListener -------------------------------------------------------- void SAL_CALL ChildWindowPane::disposing (const lang::EventObject& rEvent) throw (RuntimeException) { ThrowIfDisposed(); if (rEvent.Source == mxWindow) { // The window is gone but the pane remains alive. The next call to // GetWindow() may create the window anew. mxWindow = NULL; mpWindow = NULL; } } } } // end of namespace sd::framework