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 import java.awt.event.ActionListener;
25 import javax.swing.*;
26 import java.awt.*;
27 import java.util.*;
28 
29 import com.sun.star.awt.XFocusListener;
30 import com.sun.star.uno.UnoRuntime;
31 import com.sun.star.bridge.XUnoUrlResolver;
32 import com.sun.star.lang.XMultiServiceFactory;
33 import com.sun.star.accessibility.*;
34 import com.sun.star.awt.XExtendedToolkit;
35 
36 
37 /** This timer task tries to connect to a running Office application in regular
38     intervals until a connection can be successfully established.
39 */
40 class ConnectionTask
41     extends TimerTask
42 {
ConnectionTask(EventListenerProxy xListener)43     public ConnectionTask (EventListenerProxy xListener)
44     {
45         Init (xListener);
46     }
47 
Init(EventListenerProxy xListener)48     private void Init (EventListenerProxy xListener)
49     {
50         mxListener = xListener;
51         mbInitialized = false;
52 
53         maTimer = new java.util.Timer ();
54         maTimer.schedule (this, 0, mnPeriod);
55     }
56 
57 
58     /** This method is run every time the task is executed.  It tries to
59         connect to and register the listener at an Office application.  If it
60         can establish a connection it terminates the timer task.  Otherwise it
61         waits until the next activation.
62     */
run()63     public void run ()
64     {
65         if (registerListeners())
66         {
67             // Focus listener was successfully registered so we can cancel this task.
68             MessageArea.println ("\nconnected successfully to office");
69             cancel ();
70             maTimer = null;
71         }
72     }
73 
74 
75 
76 
77     /** Try to register the listener.
78     */
registerListeners()79     private boolean registerListeners ()
80     {
81         // Get toolkit.
82         XExtendedToolkit xToolkit = getToolkit ();
83 
84         // Register at toolkit as focus event listener.
85         if (xToolkit != null)
86         {
87             xToolkit.addTopWindowListener (mxListener);
88             int nTopWindowCount = xToolkit.getTopWindowCount();
89             try
90             {
91                 com.sun.star.lang.EventObject aEvent = new com.sun.star.lang.EventObject();
92                 for (int i=0; i<nTopWindowCount; i++)
93                 {
94                     XAccessible xAccessible = (XAccessible) UnoRuntime.queryInterface(
95                         XAccessible.class,
96                         xToolkit.getTopWindow(i));
97                     XAccessibleContext xContext = xAccessible.getAccessibleContext();
98                     if (xContext.getAccessibleName().length() > 0)
99                     {
100                         // Simulate an event that leads to registration the
101                         // listener at the window.
102                         aEvent.Source = xToolkit.getTopWindow(i);
103                         mxListener.windowOpened (aEvent);
104                     }
105                 }
106             }
107 
108             catch (com.sun.star.lang.IndexOutOfBoundsException aException)
109             {
110                 // This exception signals that the number of top windows has
111                 // changed since our last call to getTopWindowCount().
112             }
113             return true;
114         }
115         else
116             return false;
117     }
118 
119 
120 
121 
122     /** Get the toolkit from an Office which can then be used to register
123         the listener.
124     */
getToolkit()125     private XExtendedToolkit getToolkit ()
126     {
127         XMultiServiceFactory xFactory = connectToOffice();
128 
129         // Get toolkit.
130         XExtendedToolkit xToolkit = null;
131         try
132         {
133             if (xFactory != null)
134             {
135                 xToolkit = (XExtendedToolkit) UnoRuntime.queryInterface(
136                     XExtendedToolkit.class,
137                     xFactory.createInstance ("stardiv.Toolkit.VCLXToolkit"));
138             }
139         }
140         catch (com.sun.star.uno.Exception aException)
141         {
142             MessageArea.println ("caught exception while creating extended toolkit");
143             // Ignored.
144         }
145 
146         return xToolkit;
147     }
148 
149 
150 
151 
152     /** Connect to a running (Star|Open)Office application
153     */
connectToOffice()154     private XMultiServiceFactory connectToOffice ()
155     {
156         // connect to a running office and get the ServiceManager
157         try
158         {
159             com.sun.star.uno.XComponentContext xCmpContext = null;
160 
161             // get the remote office component context
162             xCmpContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
163             if( xCmpContext != null )
164                 System.out.println("Connected to a running office ...");
165 
166             // get the remote office service manager
167             com.sun.star.lang.XMultiComponentFactory xMCF =
168                 xCmpContext.getServiceManager();
169 
170             return (XMultiServiceFactory) UnoRuntime.queryInterface (
171                 XMultiServiceFactory.class, xMCF);
172         }
173 
174         catch (Exception e)
175         {
176             if ( ! mbInitialized)
177                 MessageArea.println ("Could not connect to office");
178             else
179                 MessageArea.print (".");
180         }
181         mbInitialized = true;
182         return null;
183     }
184 
185     /** Time in milliseconds between two attempts to connect to an Office
186          application.
187     */
188     private int mnPeriod = 1000;
189 
190     private EventListenerProxy mxListener;
191     private boolean mbInitialized;
192 
193     /** This timer is used for the registration loop to retry to connect to
194         the Office until a connection can be established.
195     */
196     private java.util.Timer maTimer;
197 }
198