1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "precompiled_sd.hxx" 29 30 #include "ChildWindowPane.hxx" 31 32 #include "PaneDockingWindow.hxx" 33 #include "ViewShellBase.hxx" 34 #include "ViewShellManager.hxx" 35 #include "framework/FrameworkHelper.hxx" 36 #include <toolkit/helper/vclunohelper.hxx> 37 #include <vcl/svapp.hxx> 38 39 using namespace ::com::sun::star; 40 using namespace ::com::sun::star::uno; 41 using namespace ::com::sun::star::drawing::framework; 42 43 namespace sd { namespace framework { 44 45 46 ChildWindowPane::ChildWindowPane ( 47 const Reference<XResourceId>& rxPaneId, 48 sal_uInt16 nChildWindowId, 49 ViewShellBase& rViewShellBase, 50 ::std::auto_ptr<SfxShell> pShell) 51 : ChildWindowPaneInterfaceBase(rxPaneId,(::Window*)NULL), 52 mnChildWindowId(nChildWindowId), 53 mrViewShellBase(rViewShellBase), 54 mpShell(pShell), 55 mbHasBeenActivated(false) 56 { 57 mrViewShellBase.GetViewShellManager()->ActivateShell(mpShell.get()); 58 59 SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame(); 60 if (pViewFrame != NULL) 61 { 62 if (mrViewShellBase.IsActive()) 63 { 64 if (pViewFrame->KnowsChildWindow(mnChildWindowId)) 65 { 66 if (pViewFrame->HasChildWindow(mnChildWindowId)) 67 { 68 // The ViewShellBase has already been activated. Make 69 // the child window visible as soon as possible. 70 pViewFrame->SetChildWindow(mnChildWindowId, sal_True); 71 OSL_TRACE("ChildWindowPane:activating now"); 72 } 73 else 74 { 75 // The window is created asynchronously. Rely on the 76 // ConfigurationUpdater to try another update, and with 77 // that another request for this window, in a short 78 // time. 79 OSL_TRACE("ChildWindowPane:activated asynchronously"); 80 } 81 } 82 else 83 { 84 OSL_TRACE("ChildWindowPane:not known"); 85 } 86 } 87 else 88 { 89 // The ViewShellBase has not yet been activated. Hide the 90 // window and wait a little before it is made visible. See 91 // comments in the GetWindow() method for an explanation. 92 pViewFrame->SetChildWindow(mnChildWindowId, sal_False); 93 OSL_TRACE("ChildWindowPane:base not active"); 94 } 95 } 96 } 97 98 99 100 101 ChildWindowPane::~ChildWindowPane (void) throw() 102 { 103 } 104 105 106 107 108 void ChildWindowPane::Hide (void) 109 { 110 SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame(); 111 if (pViewFrame != NULL) 112 if (pViewFrame->KnowsChildWindow(mnChildWindowId)) 113 if (pViewFrame->HasChildWindow(mnChildWindowId)) 114 pViewFrame->SetChildWindow(mnChildWindowId, sal_False); 115 116 // Release the window because when the child window is shown again it 117 // may use a different window. 118 mxWindow = NULL; 119 } 120 121 122 123 124 void SAL_CALL ChildWindowPane::disposing (void) 125 { 126 ::osl::MutexGuard aGuard (maMutex); 127 128 mrViewShellBase.GetViewShellManager()->DeactivateShell(mpShell.get()); 129 mpShell.reset(); 130 131 if (mxWindow.is()) 132 { 133 mxWindow->removeEventListener(this); 134 } 135 136 Pane::disposing(); 137 } 138 139 140 141 142 ::Window* ChildWindowPane::GetWindow (void) 143 { 144 do 145 { 146 if (mxWindow.is()) 147 // Window already exists => nothing to do. 148 break; 149 150 // When the window is not yet present then obtain it only when the 151 // shell has already been activated. The activation is not 152 // necessary for the code to work properly but is used to optimize 153 // the layouting and displaying of the window. When it is made 154 // visible to early then some layouting seems to be made twice or at 155 // an inconvenient time and the overall process of initializing the 156 // Impress takes longer. 157 if ( ! mbHasBeenActivated && mpShell.get()!=NULL && ! mpShell->IsActive()) 158 break; 159 160 mbHasBeenActivated = true; 161 SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame(); 162 if (pViewFrame == NULL) 163 break; 164 // The view frame has to know the child window. This can be the 165 // case, when for example the document is in read-only mode: the 166 // task pane is then not available. 167 if ( ! pViewFrame->KnowsChildWindow(mnChildWindowId)) 168 break; 169 170 pViewFrame->SetChildWindow(mnChildWindowId, sal_True); 171 SfxChildWindow* pChildWindow = pViewFrame->GetChildWindow(mnChildWindowId); 172 if (pChildWindow == NULL) 173 if (pViewFrame->HasChildWindow(mnChildWindowId)) 174 { 175 // The child window is not yet visible. Ask the view frame 176 // to show it and try again to get access to the child 177 // window. 178 pViewFrame->ShowChildWindow(mnChildWindowId, sal_True); 179 pChildWindow = pViewFrame->GetChildWindow(mnChildWindowId); 180 } 181 182 // When the child window is still not visible then we have to try later. 183 if (pChildWindow == NULL) 184 break; 185 186 // From the child window get the docking window and from that the 187 // content window that is the container for the actual content. 188 PaneDockingWindow* pDockingWindow = dynamic_cast<PaneDockingWindow*>( 189 pChildWindow->GetWindow()); 190 if (pDockingWindow == NULL) 191 break; 192 193 // At last, we have access to the window and its UNO wrapper. 194 mpWindow = &pDockingWindow->GetContentWindow(); 195 mxWindow = VCLUnoHelper::GetInterface(mpWindow); 196 197 // Register as window listener to be informed when the child window 198 // is hidden. 199 if (mxWindow.is()) 200 mxWindow->addEventListener(this); 201 } 202 while (false); 203 204 return mpWindow; 205 } 206 207 208 209 210 Reference<awt::XWindow> SAL_CALL ChildWindowPane::getWindow (void) 211 throw (RuntimeException) 212 { 213 if (mpWindow == NULL || ! mxWindow.is()) 214 GetWindow(); 215 return Pane::getWindow(); 216 } 217 218 219 220 IMPLEMENT_FORWARD_XINTERFACE2( 221 ChildWindowPane, 222 ChildWindowPaneInterfaceBase, 223 Pane); 224 IMPLEMENT_FORWARD_XTYPEPROVIDER2( 225 ChildWindowPane, 226 ChildWindowPaneInterfaceBase, 227 Pane); 228 229 230 231 232 //----- XEventListener -------------------------------------------------------- 233 234 void SAL_CALL ChildWindowPane::disposing (const lang::EventObject& rEvent) 235 throw (RuntimeException) 236 { 237 ThrowIfDisposed(); 238 239 if (rEvent.Source == mxWindow) 240 { 241 // The window is gone but the pane remains alive. The next call to 242 // GetWindow() may create the window anew. 243 mxWindow = NULL; 244 mpWindow = NULL; 245 } 246 } 247 248 249 250 251 } } // end of namespace sd::framework 252