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 package com.sun.star.comp.beans;
25 
26 import java.awt.Component;
27 
28 import com.sun.star.lang.EventObject;
29 import com.sun.star.lang.SystemDependent;
30 import com.sun.star.lang.XEventListener;
31 import com.sun.star.lang.XMultiServiceFactory;
32 import com.sun.star.lang.XMultiComponentFactory;
33 import com.sun.star.awt.Rectangle;
34 import com.sun.star.awt.XWindow;
35 import com.sun.star.awt.XWindowPeer;
36 import com.sun.star.awt.XVclWindowPeer;
37 import com.sun.star.awt.XToolkit;
38 import com.sun.star.awt.WindowDescriptor;
39 import com.sun.star.awt.WindowAttribute;
40 import com.sun.star.awt.WindowClass;
41 import com.sun.star.uno.UnoRuntime;
42 import com.sun.star.uno.XComponentContext;
43 import com.sun.star.uno.Any;
44 import com.sun.star.uno.Type;
45 import com.sun.star.beans.NamedValue;
46 
47 /**
48  * This class represents a local office window.
49  *
50  * @since OOo 2.0.0
51  */
52 public class LocalOfficeWindow
53 	extends java.awt.Canvas
54 	implements OfficeWindow, XEventListener
55 {
56 	private transient OfficeConnection	mConnection;
57 	private transient XWindowPeer		mParentProxy;
58 	private transient XWindowPeer		mWindow;
59 	private boolean 			bPeer = false;
60 
61 	/**
62 	 * Construnctor.
63 	 *
64 	 * @param connection The office connection object the window
65 	 *	belongs to.
66 	 */
LocalOfficeWindow(OfficeConnection connection)67 	protected LocalOfficeWindow(OfficeConnection connection)
68 	{
69 		mConnection	= connection;
70 		mConnection.addEventListener((XEventListener)this);
71 	}
72 
73 	/**
74 	 * Retrives an AWT component object associated with the OfficeWindow.
75 	 *
76 	 * @return The AWT component object associated with the OfficeWindow.
77 	 */
getAWTComponent()78 	public Component getAWTComponent()
79 	{
80 		return this;
81 	}
82 
83 	/**
84 	 * Retrives an UNO XWindowPeer object associated with the OfficeWindow.
85 	 *
86 	 * @return The UNO XWindowPeer object associated with the OfficeWindow.
87 	 */
getUNOWindowPeer()88 	public XWindowPeer getUNOWindowPeer()
89 	{
90 		if (mWindow == null)
91 			createUNOWindowPeer();
92 		return mWindow;
93 	}
94 
95 	/**
96 	 * Receives a notification about the connection has been closed.
97 	 * This method has to set the connection to <code>null</code>.
98 	 *
99 	 * @source The event object.
100 	 */
disposing(EventObject source)101 	public void disposing(EventObject source)
102 	{
103 		// the window will be disposed by the framework
104 		mWindow = null;
105 		mConnection	= null;
106 	}
107 
108 	/**
109 	* Returns an AWT toolkit.
110         */
queryAWTToolkit()111        private XToolkit queryAWTToolkit()
112                throws com.sun.star.uno.Exception
113        {
114 			// Create a UNO toolkit.
115 			XMultiComponentFactory  compfactory;
116 			XComponentContext xContext = mConnection.getComponentContext();
117 			if ( xContext != null )
118 			{
119 				compfactory     = mConnection.getComponentContext().getServiceManager();
120 				XMultiServiceFactory    factory;
121 				factory = (XMultiServiceFactory)UnoRuntime.queryInterface(
122 						XMultiServiceFactory.class, compfactory);
123 				Object          object  = factory.createInstance( "com.sun.star.awt.Toolkit");
124 				return (XToolkit)UnoRuntime.queryInterface(XToolkit.class, object);
125 			}
126 			else
127 				return null;
128        }
129 
130        	/// called when system parent is available, reparents the bean window
aquireSystemWindow()131 	private synchronized void aquireSystemWindow()
132 	{
133 		if ( !bPeer )
134 		{
135 			// set real parent
136 			XVclWindowPeer xVclWindowPeer = (XVclWindowPeer)UnoRuntime.queryInterface(
137                                XVclWindowPeer.class, mWindow);
138 
139 			xVclWindowPeer.setProperty( "PluginParent", getWrappedWindowHandle());
140 			bPeer = true;
141             // show document window
142 			XWindow aWindow = (XWindow)UnoRuntime.queryInterface(XWindow.class, mWindow);
143 			aWindow.setVisible( true );
144 		}
145 	}
146 
147        	/// called when system parent is about to die, reparents the bean window
releaseSystemWindow()148 	private synchronized void releaseSystemWindow()
149 	{
150 		if ( bPeer )
151 		{
152 		       	// hide document window
153 			XWindow aWindow = (XWindow)UnoRuntime.queryInterface(XWindow.class, mWindow);
154 			aWindow.setVisible( false );
155 
156 			// set null parent
157 			XVclWindowPeer xVclWindowPeer = (XVclWindowPeer)UnoRuntime.queryInterface(
158                                XVclWindowPeer.class, mWindow);
159 			xVclWindowPeer.setProperty( "PluginParent", new Long(0) );
160 			bPeer = false;
161 		}
162 	}
163 
164 
165 	/// Overriding java.awt.Component.setVisible() due to Java bug (no showing event).
setVisible( boolean b )166 	public void setVisible( boolean b )
167 	{
168 		super.setVisible(b);
169 
170 		// Java-Bug: componentShown() is never called :-(
171 		// is still at least in Java 1.4.1_02
172 		if ( b )
173 			aquireSystemWindow();
174 		else
175 			releaseSystemWindow();
176 	}
177 
178        /** Factory method for a UNO AWT toolkit window as a child of this Java window.
179 	*
180 	*/
createUNOWindowPeer()181        private synchronized XWindowPeer createUNOWindowPeer()
182        {
183 		try
184 		{
185 			// get this windows native window type
186             int type = getNativeWindowSystemType();
187 
188             // Java AWT windows only have a system window when showing.
189             XWindowPeer parentPeer;
190             if ( isShowing() )
191             {
192 				// create direct parent relationship
193 				//setVisible( true );
194                 parentPeer = new JavaWindowPeerFake(getWrappedWindowHandle(), type);
195 				bPeer = true;
196                         }
197                         else
198 			{
199 				// no parent yet
200 				parentPeer = null;
201 				bPeer = false;
202 			}
203 
204 			// create native window (mWindow)
205 			Rectangle aRect = new Rectangle( 0, 0, 20, 20 );
206 			WindowDescriptor desc = new WindowDescriptor();
207 			desc.Type = WindowClass.TOP;
208 			desc.Parent = parentPeer;
209 			desc.Bounds = aRect;
210 			desc.WindowServiceName = "workwindow";
211 			desc.WindowAttributes = (type == SystemDependent.SYSTEM_WIN32)
212 				? WindowAttribute.SHOW : 0;
213 			mWindow	= queryAWTToolkit().createWindow(desc);
214 
215 
216 			// set initial visibility
217             XWindow aWindow = (XWindow)UnoRuntime.queryInterface(XWindow.class, mWindow);
218 			aWindow.setVisible( bPeer );
219 		}
220 		catch (com.sun.star.uno.Exception exp) {
221 		}
222 
223 		return mWindow;
224 	}
225     /** We make sure that the office window is notified that the parent
226      *  will be removed.
227      */
removeNotify()228     public void removeNotify()
229     {
230         try {
231             releaseSystemWindow();
232         } catch (java.lang.Exception e) {
233             System.err.println("LocaleOfficeWindow.removeNotify: Exception in releaseSystemWindow.");
234             System.err.println(e.getMessage());
235             e.printStackTrace(System.err);
236         }
237         super.removeNotify();
238     }
239 
240 	/**
241 	 * Retrives a platform dependant system window identifier.
242 	 *
243 	 * @return The system window identifier.
244 	 */
getNativeWindow()245     private native long getNativeWindow();
246 
247 	/**
248 	 * Retrives a platform dependant system window type.
249 	 *
250 	 * @return The system window type.
251 	 */
getNativeWindowSystemType()252 	private native int getNativeWindowSystemType();
253 
254     /**
255     Returns an Any containing a sequences of com.sun.star.beans.NamedValue. One NamedValue
256     contains the name "WINDOW" and the value is a Long representing the window handle.
257     The second NamedValue  has the name "XEMBED" and the value is true, when the XEmbed
258     protocol shall be used fore embedding the native Window.
259     */
getWrappedWindowHandle()260     protected Any getWrappedWindowHandle()
261     {
262 
263         NamedValue window = new NamedValue(
264             "WINDOW", new Any(new Type(Long.class), new Long(getNativeWindow())));
265         NamedValue xembed = new NamedValue(
266             "XEMBED", new Any(new Type(Boolean.class), new Boolean(false)));
267 
268         if (getNativeWindowSystemType() == SystemDependent.SYSTEM_XWINDOW )
269         {
270             String vendor = System.getProperty("java.vendor");
271             if (vendor.equals("Sun Microsystems Inc.")
272                 && Boolean.valueOf(System.getProperty("sun.awt.xembedserver")).booleanValue())
273             {
274                 xembed = new NamedValue(
275                     "XEMBED",
276                     new Any(new Type(Boolean.class), new Boolean(true)));
277             }
278         }
279         return new Any(
280             new Type("[]com.sun.star.beans.NamedValue"),
281             new NamedValue[] {window, xembed});
282     }
283 
284 }
285