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