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 // __________ Imports __________ 25 26 import com.sun.star.uno.UnoRuntime; 27 28 import java.awt.*; 29 import java.awt.event.*; 30 import java.lang.*; 31 import java.net.*; 32 import javax.swing.*; 33 import javax.swing.border.*; 34 import java.awt.AWTEvent; 35 import java.awt.event.WindowEvent; 36 37 // __________ Implementation __________ 38 39 /** 40 * This implement a java frame wich contains 41 * an office document, shows some status informations 42 * about that, provides simple functionality on it 43 * (e.g. toggle menubar, save document) and 44 * react for different situations independent 45 * (e.g. closing the document from outside). 46 * Every instance of this class will be a member 47 * inside the global "ViewContainer" of this java 48 * demo application which holds all opened views alive. 49 * 50 * @author Andreas Schlüns 51 * @created 06.03.2002 09:38 52 */ 53 public class DocumentView extends JFrame 54 implements com.sun.star.lang.XEventListener, // react for Frame::disposing() 55 IShutdownListener // react for System.exit() 56 { 57 // ____________________ 58 59 /** 60 * const 61 * These command strings are used to identify a received action 62 * of buttons on which we listen for action events. 63 */ 64 public static final String COMMAND_OPEN = "open" ; 65 public static final String COMMAND_SAVE = "save" ; 66 public static final String COMMAND_EXPORT = "export" ; 67 public static final String COMMAND_EXIT = "exit" ; 68 69 // ____________________ 70 71 /** 72 * @member mxFrame office frame which contains the document of this view 73 * 74 * @member maStatusView special panel wich show available status informations of currently loaded document 75 * @member maDocumentView use JNI mechanism to plug an office window into our own java UI container (used for inplace mode only!) 76 * @member maCustomizeView special panel makes it possible to toggle menubar/toolbar or objectbar of loaded document 77 * @member maInterceptor interceptor thread which intercept "new" menu of office frame to open new frames inside this java application 78 * 79 * @member msName unique name of this view (returned by the global ViewContainer during registration) 80 * 81 * @member mbOpen button to open documents 82 * @member mbSave button to save currently loaded document 83 * @member mbExport button to save currently loaded document in HTML format (if it is possible!) 84 * @member mbExit button to exit this demo 85 * 86 * @member maInterception we try to intercept the file->new menu to open new document inside this java application 87 */ 88 private com.sun.star.frame.XFrame mxFrame ; 89 90 private StatusView maStatusView ; 91 private NativeView maDocumentView ; 92 private CustomizeView maCustomizeView ; 93 private Interceptor maInterceptor ; 94 95 private String msName ; 96 97 private JButton mbtOpen ; 98 private JButton mbtSave ; 99 private JButton mbtExport ; 100 private JButton mbtExit ; 101 102 private boolean mbDead ; 103 104 // ____________________ 105 106 /** 107 * ctor 108 * Create view controls on startup and initialize it with default values. 109 */ DocumentView()110 DocumentView() 111 { 112 this.setSize( new Dimension(800,600) ); 113 114 JPanel paMainPanel = (JPanel)this.getContentPane(); 115 116 // create and add command buttons to a panel 117 // it will be a sub panel of later layouted UI 118 mbtOpen = new JButton("Open ..." ); 119 mbtSave = new JButton("Save" ); 120 mbtExport = new JButton("Save as HTML ..."); 121 mbtExit = new JButton("Exit" ); 122 123 mbtOpen.setEnabled (true ); 124 mbtSave.setEnabled (false); 125 mbtExport.setEnabled(false); 126 mbtExit.setEnabled (true ); 127 128 mbtOpen.setActionCommand (COMMAND_OPEN ); 129 mbtSave.setActionCommand (COMMAND_SAVE ); 130 mbtExport.setActionCommand(COMMAND_EXPORT); 131 mbtExit.setActionCommand (COMMAND_EXIT ); 132 133 Reactor aListener = new Reactor(); 134 mbtOpen.addActionListener (aListener); 135 mbtSave.addActionListener (aListener); 136 mbtExport.addActionListener(aListener); 137 mbtExit.addActionListener (aListener); 138 139 JPanel paCommands = new JPanel( new GridLayout(4,0) ); 140 paCommands.add(mbtOpen); 141 paCommands.add(mbtSave); 142 paCommands.add(mbtExport); 143 paCommands.add(mbtExit); 144 145 // create view to show status informations of opened file 146 maStatusView = new StatusView(); 147 148 // create view for toggle different bar's of document 149 maCustomizeView = new CustomizeView(); 150 151 paCommands.setBorder ( new TitledBorder(BorderFactory.createEtchedBorder(),"Commands") ); 152 maStatusView.setBorder ( new TitledBorder(BorderFactory.createEtchedBorder(),"Status Informations") ); 153 maCustomizeView.setBorder( new TitledBorder(BorderFactory.createEtchedBorder(),"Customize Document View") ); 154 155 // layout the whole UI 156 JPanel paTest = new JPanel(new GridLayout(3,0)); 157 paTest.add(paCommands ); 158 paTest.add(maStatusView ); 159 paTest.add(maCustomizeView); 160 JScrollPane paScroll = new JScrollPane(); 161 paScroll.getViewport().add(paTest,null); 162 163 if(ViewContainer.mbInplace==true) 164 { 165 // create view to show opened documents 166 // This special view is neccessary for inplace mode only! 167 maDocumentView = new NativeView(); 168 169 JSplitPane paSplit = new JSplitPane(); 170 paSplit.setOneTouchExpandable( true ); 171 172 paSplit.setLeftComponent (maDocumentView); 173 paSplit.setRightComponent(paScroll ); 174 175 paMainPanel.add(paSplit); 176 } 177 else 178 { 179 paMainPanel.add(paScroll); 180 } 181 182 // Register this new view on our global view container. 183 msName = FunctionHelper.getUniqueFrameName(); 184 this.setTitle(msName); 185 ViewContainer.getGlobalContainer().addView(this); 186 ViewContainer.getGlobalContainer().addListener(this); 187 // be listener for closing the application 188 this.enableEvents(AWTEvent.WINDOW_EVENT_MASK); 189 } 190 191 // ____________________ 192 193 /** 194 * Create the view frame for showing the office documents on demand. 195 * Dependend from given command line parameter we create 196 * an office XFrame and initialize it with a window. This 197 * window can be a pure toolkit window (means toolkit of office!) 198 * or a plugged java canvas - office window combination. 199 */ createFrame()200 public void createFrame() 201 { 202 // create view frame (as a XFrame!) here 203 // Look for right view mode setted by user command line parameter. 204 // First try to get a new unambigous frame name from our global ViewContainer. 205 if(ViewContainer.mbInplace==true) 206 { 207 // inplace document view can't be initialized without a visible parent window hierarchy! 208 // So make shure that we are visible in every case! 209 this.setVisible(true); 210 mxFrame = FunctionHelper.createViewFrame(msName,maDocumentView); 211 } 212 else 213 mxFrame = FunctionHelper.createViewFrame(msName,null); 214 215 if(mxFrame!=null) 216 { 217 // start interception 218 maInterceptor = new Interceptor(mxFrame); 219 maInterceptor.startListening(); 220 221 // start listening for status events and actualization 222 // of our status view 223 // (of course for our CustomizeView too) 224 maStatusView.setFrame (mxFrame); 225 maCustomizeView.setFrame(mxFrame); 226 227 // be listener for closing the remote target view frame 228 com.sun.star.lang.XComponent xBroadcaster = (com.sun.star.lang.XComponent)UnoRuntime.queryInterface( 229 com.sun.star.lang.XComponent.class, 230 mxFrame); 231 232 if(xBroadcaster!=null) 233 xBroadcaster.addEventListener(this); 234 } 235 } 236 237 // ____________________ 238 239 /** 240 * Different ways to load any URL from outside (may be by the command line) 241 * into this document view or to save it. 242 */ load(String sURL)243 public void load(String sURL) 244 { 245 load(sURL,new com.sun.star.beans.PropertyValue[0]); 246 } 247 248 // ____________________ 249 load(String sURL, com.sun.star.beans.PropertyValue[] lArguments)250 public void load(String sURL, com.sun.star.beans.PropertyValue[] lArguments) 251 { 252 com.sun.star.lang.XComponent xDocument = FunctionHelper.loadDocument(mxFrame,sURL,lArguments); 253 if(xDocument!=null) 254 { 255 mbtSave.setEnabled (true); 256 mbtExport.setEnabled(true); 257 } 258 else 259 { 260 mbtSave.setEnabled (false); 261 mbtExport.setEnabled(false); 262 } 263 } 264 265 // ____________________ 266 save()267 public void save() 268 { 269 com.sun.star.frame.XController xController = mxFrame.getController(); 270 if (xController==null) 271 return; 272 com.sun.star.frame.XModel xDocument = xController.getModel(); 273 if (xDocument==null) 274 return; 275 FunctionHelper.saveDocument(xDocument); 276 } 277 278 // ____________________ 279 exportHTML(String sURL)280 public void exportHTML(String sURL) 281 { 282 com.sun.star.frame.XController xController = mxFrame.getController(); 283 if (xController==null) 284 return; 285 com.sun.star.frame.XModel xDocument = xController.getModel(); 286 if (xDocument==null) 287 return; 288 FunctionHelper.saveAsHTML(xDocument,sURL); 289 } 290 291 // ____________________ 292 293 /** 294 * Overridden so we can react for window closing of this view. 295 */ processWindowEvent(WindowEvent aEvent)296 protected void processWindowEvent(WindowEvent aEvent) 297 { 298 if (aEvent.getID()!=WindowEvent.WINDOW_CLOSING) 299 { 300 super.processWindowEvent(aEvent); 301 } 302 else 303 if (FunctionHelper.closeFrame(mxFrame)) 304 { 305 mxFrame = null; 306 shutdown(); 307 super.processWindowEvent(aEvent); 308 } 309 } 310 311 // ____________________ 312 313 /** 314 * Here we can react for System.exit() normaly. 315 * But we use it for disposing() or windowClosing() too. 316 */ shutdown()317 public void shutdown() 318 { 319 if (mbDead) 320 return; 321 mbDead=true; 322 323 // force these sub view to release her remote 324 // refrences too! 325 maStatusView.shutdown(); 326 maCustomizeView.shutdown(); 327 328 maStatusView = null; 329 maCustomizeView = null; 330 331 // disable all interceptions 332 maInterceptor.shutdown(); 333 maInterceptor = null; 334 335 // close the frame and his document 336 // Relaesing of our listener connections for disposing() 337 // will be forced automaticly then. Because the frame 338 // will call us back ... 339 if (mxFrame!=null) 340 FunctionHelper.closeFrame(mxFrame); 341 342 // deregister this view in the global container 343 // Normaly we should die afterwards by garbage collection ... 344 // In cease this was the last view - it force a system.exit(). 345 // But then we are no longer a member of the global container 346 // of possible shutdown listener ... and this method should be 347 // called again. 348 ViewContainer.getGlobalContainer().removeView(this); 349 } 350 351 // ____________________ 352 353 /** 354 * callback from our internal saved frame 355 * which wish to die. Its not neccessary to remove listener connections 356 * here. Because the broadcaster do it automaticly. 357 * We have to release all references to him only. 358 * 359 * @param aSource 360 * describe the broadcaster of this event 361 * Must be our internal saved frame. 362 */ disposing(com.sun.star.lang.EventObject aSource)363 public void disposing(com.sun.star.lang.EventObject aSource) 364 { 365 mxFrame = null; 366 } 367 368 // ____________________ 369 370 /** 371 * This inner class is used to react for events of our own UI controls. 372 * So we can start different actions then. 373 */ 374 private class Reactor implements ActionListener 375 { 376 // ____________________ 377 378 /** 379 * This method react for pressed buttons or selected check boxes. 380 */ actionPerformed(ActionEvent aEvent)381 public void actionPerformed(ActionEvent aEvent) 382 { 383 String sCommand = aEvent.getActionCommand(); 384 //----------------------------- 385 // open any file from disk 386 if( sCommand.compareTo(COMMAND_OPEN) == 0 ) 387 { 388 String sURL = FunctionHelper.askUserForFileURL(DocumentView.this,true); 389 if(sURL!=null) 390 DocumentView.this.load(sURL); 391 } 392 else 393 //----------------------------- 394 // save current document 395 if( sCommand.compareTo(COMMAND_SAVE) == 0 ) 396 { 397 DocumentView.this.save(); 398 } 399 else 400 //----------------------------- 401 // export current document to html 402 if( sCommand.compareTo(COMMAND_EXPORT) == 0 ) 403 { 404 String sURL = FunctionHelper.askUserForFileURL(DocumentView.this,false); 405 if(sURL!=null) 406 DocumentView.this.exportHTML(sURL); 407 } 408 else 409 //----------------------------- 410 // exit application 411 if( sCommand.compareTo(COMMAND_EXIT) == 0 ) 412 { 413 // This will force deleting of this and 414 // all other currently opened views automaticly! 415 System.exit(0); 416 } 417 } 418 } 419 } 420