Get the style color and number just once
[LibreOffice.git] / odk / examples / DevelopersGuide / OfficeDev / DesktopEnvironment / DocumentView.java
blob57ac4e77951eef77a048c864cd60660cf9863e6a
1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * the BSD license.
7 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
29 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
31 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
32 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *************************************************************************/
36 // __________ Imports __________
38 import com.sun.star.uno.UnoRuntime;
40 import java.awt.*;
41 import java.awt.event.*;
42 import javax.swing.*;
43 import javax.swing.border.*;
44 import java.awt.AWTEvent;
45 import java.awt.event.WindowEvent;
47 // __________ Implementation __________
49 /**
50 * This implement a java frame which contains
51 * an office document, shows some status information
52 * about that, provides simple functionality on it
53 * (e.g. toggle menubar, save document) and
54 * react for different situations independent
55 * (e.g. closing the document from outside).
56 * Every instance of this class will be a member
57 * inside the global "ViewContainer" of this java
58 * demo application which holds all opened views alive.
61 public class DocumentView extends JFrame
62 implements com.sun.star.lang.XEventListener, // react for Frame::disposing()
63 IShutdownListener // react for System.exit()
67 /**
68 * const
69 * These command strings are used to identify a received action
70 * of buttons on which we listen for action events.
72 private static final String COMMAND_OPEN = "open" ;
73 private static final String COMMAND_SAVE = "save" ;
74 private static final String COMMAND_EXPORT = "export" ;
75 private static final String COMMAND_EXIT = "exit" ;
79 /**
80 * @member mxFrame office frame which contains the document of this view
82 * @member maStatusView special panel which shows available status information of currently loaded document
83 * @member maDocumentView use JNI mechanism to plug an office window into our own java UI container (used for inplace mode only!)
84 * @member maCustomizeView special panel makes it possible to toggle menubar/toolbar or objectbar of loaded document
85 * @member maInterceptor interceptor thread which intercept "new" menu of office frame to open new frames inside this java application
87 * @member msName unique name of this view (returned by the global ViewContainer during registration)
89 * @member mbOpen button to open documents
90 * @member mbSave button to save currently loaded document
91 * @member mbExport button to save currently loaded document in HTML format (if it is possible!)
92 * @member mbExit button to exit this demo
94 * @member maInterception we try to intercept the file->new menu to open new document inside this java application
96 private com.sun.star.frame.XFrame mxFrame ;
98 private StatusView maStatusView ;
99 private NativeView maDocumentView ;
100 private CustomizeView maCustomizeView ;
101 private Interceptor maInterceptor ;
103 private final String msName;
105 private final JButton mbtSave;
106 private final JButton mbtExport;
108 private boolean mbDead ;
113 * ctor
114 * Create view controls on startup and initialize it with default values.
116 DocumentView()
118 this.setSize( new Dimension(800,600) );
120 JPanel paMainPanel = (JPanel)this.getContentPane();
122 // create and add command buttons to a panel
123 // it will be a sub panel of later layouted UI
124 JButton mbtOpen = new JButton("Open ..." );
125 mbtSave = new JButton("Save" );
126 mbtExport = new JButton("Save as HTML ...");
127 JButton mbtExit = new JButton("Exit" );
129 mbtOpen.setEnabled (true );
130 mbtSave.setEnabled (false);
131 mbtExport.setEnabled(false);
132 mbtExit.setEnabled (true );
134 mbtOpen.setActionCommand (COMMAND_OPEN );
135 mbtSave.setActionCommand (COMMAND_SAVE );
136 mbtExport.setActionCommand(COMMAND_EXPORT);
137 mbtExit.setActionCommand (COMMAND_EXIT );
139 Reactor aListener = new Reactor();
140 mbtOpen.addActionListener (aListener);
141 mbtSave.addActionListener (aListener);
142 mbtExport.addActionListener(aListener);
143 mbtExit.addActionListener (aListener);
145 JPanel paCommands = new JPanel( new GridLayout(4,0) );
146 paCommands.add(mbtOpen);
147 paCommands.add(mbtSave);
148 paCommands.add(mbtExport);
149 paCommands.add(mbtExit);
151 // create view to show status information of opened file
152 maStatusView = new StatusView();
154 // create view for toggle different bar's of document
155 maCustomizeView = new CustomizeView();
157 paCommands.setBorder ( new TitledBorder(BorderFactory.createEtchedBorder(),"Commands") );
158 maStatusView.setBorder ( new TitledBorder(BorderFactory.createEtchedBorder(),"Status Information") );
159 maCustomizeView.setBorder( new TitledBorder(BorderFactory.createEtchedBorder(),"Customize Document View") );
161 // layout the whole UI
162 JPanel paTest = new JPanel(new GridLayout(3,0));
163 paTest.add(paCommands );
164 paTest.add(maStatusView );
165 paTest.add(maCustomizeView);
166 JScrollPane paScroll = new JScrollPane();
167 paScroll.getViewport().add(paTest,null);
169 if(ViewContainer.mbInplace)
171 // create view to show opened documents
172 // This special view is necessary for inplace mode only!
173 maDocumentView = new NativeView();
175 JSplitPane paSplit = new JSplitPane();
176 paSplit.setOneTouchExpandable( true );
178 paSplit.setLeftComponent (maDocumentView);
179 paSplit.setRightComponent(paScroll );
181 paMainPanel.add(paSplit);
183 else
185 paMainPanel.add(paScroll);
188 // Register this new view on our global view container.
189 msName = FunctionHelper.getUniqueFrameName();
190 this.setTitle(msName);
191 ViewContainer.getGlobalContainer().addView(this);
192 ViewContainer.getGlobalContainer().addListener(this);
193 // be listener for closing the application
194 this.enableEvents(AWTEvent.WINDOW_EVENT_MASK);
200 * Create the view frame for showing the office documents on demand.
201 * Depending on given command line parameter we create
202 * an office XFrame and initialize it with a window. This
203 * window can be a pure toolkit window (means toolkit of office!)
204 * or a plugged java canvas - office window combination.
206 public void createFrame()
208 // create view frame (as a XFrame!) here
209 // Look for right view mode set by user command line parameter.
210 // First try to get a new unambiguous frame name from our global ViewContainer.
211 if(ViewContainer.mbInplace)
213 // inplace document view can't be initialized without a visible parent window hierarchy!
214 // So make sure that we are visible in every case!
215 this.setVisible(true);
216 mxFrame = FunctionHelper.createViewFrame(msName,maDocumentView);
218 else
219 mxFrame = FunctionHelper.createViewFrame(msName,null);
221 if(mxFrame!=null)
223 // start interception
224 maInterceptor = new Interceptor(mxFrame);
225 maInterceptor.startListening();
227 // start listening for status events and actualization
228 // of our status view
229 // (of course for our CustomizeView too)
230 maStatusView.setFrame (mxFrame);
231 maCustomizeView.setFrame(mxFrame);
233 // be listener for closing the remote target view frame
234 com.sun.star.lang.XComponent xBroadcaster = UnoRuntime.queryInterface(
235 com.sun.star.lang.XComponent.class,
236 mxFrame);
238 if(xBroadcaster!=null)
239 xBroadcaster.addEventListener(this);
246 * Different ways to load any URL from outside (may be by the command line)
247 * into this document view or to save it.
249 public void load(String sURL)
251 load(sURL,new com.sun.star.beans.PropertyValue[0]);
256 public void load(String sURL, com.sun.star.beans.PropertyValue[] lArguments)
258 com.sun.star.lang.XComponent xDocument = FunctionHelper.loadDocument(mxFrame,sURL,lArguments);
259 if(xDocument!=null)
261 mbtSave.setEnabled (true);
262 mbtExport.setEnabled(true);
264 else
266 mbtSave.setEnabled (false);
267 mbtExport.setEnabled(false);
273 private void save()
275 com.sun.star.frame.XController xController = mxFrame.getController();
276 if (xController==null)
277 return;
278 com.sun.star.frame.XModel xDocument = xController.getModel();
279 if (xDocument==null)
280 return;
281 FunctionHelper.saveDocument(xDocument);
286 private void exportHTML(String sURL)
288 com.sun.star.frame.XController xController = mxFrame.getController();
289 if (xController==null)
290 return;
291 com.sun.star.frame.XModel xDocument = xController.getModel();
292 if (xDocument==null)
293 return;
294 FunctionHelper.saveAsHTML(xDocument,sURL);
300 * Overridden so we can react for window closing of this view.
302 @Override
303 protected void processWindowEvent(WindowEvent aEvent)
305 if (aEvent.getID()!=WindowEvent.WINDOW_CLOSING)
307 super.processWindowEvent(aEvent);
309 else
310 if (FunctionHelper.closeFrame(mxFrame))
312 mxFrame = null;
313 shutdown();
314 super.processWindowEvent(aEvent);
321 * Here we can react for System.exit() normally.
322 * But we use it for disposing() or windowClosing() too.
324 public void shutdown()
326 if (mbDead)
327 return;
328 mbDead=true;
330 // force these sub view to release her remote
331 // references too!
332 maStatusView.shutdown();
333 maCustomizeView.shutdown();
335 maStatusView = null;
336 maCustomizeView = null;
338 // disable all interceptions
339 maInterceptor.shutdown();
340 maInterceptor = null;
342 // close the frame and his document
343 // Releasing of our listener connections for disposing()
344 // will be forced automatically then. Because the frame
345 // will call us back ...
346 if (mxFrame!=null)
347 FunctionHelper.closeFrame(mxFrame);
349 // deregister this view in the global container
350 // Normally we should die afterwards by garbage collection ...
351 // In cease this was the last view - it force a system.exit().
352 // But then we are no longer a member of the global container
353 // of possible shutdown listener ... and this method should be
354 // called again.
355 ViewContainer.getGlobalContainer().removeView(this);
361 * callback from our internal saved frame
362 * which wishes to die. It's not necessary to remove listener connections
363 * here. Because the broadcaster do it automatically.
364 * We have to release all references to him only.
366 * @param aSource
367 * describe the broadcaster of this event
368 * Must be our internal saved frame.
370 public void disposing(com.sun.star.lang.EventObject aSource)
372 mxFrame = null;
378 * This inner class is used to react for events of our own UI controls.
379 * So we can start different actions then.
381 private class Reactor implements ActionListener
386 * This method react for pressed buttons or selected check boxes.
388 public void actionPerformed(ActionEvent aEvent)
390 String sCommand = aEvent.getActionCommand();
392 // open any file from disk
393 if( sCommand.equals(COMMAND_OPEN) )
395 String sURL = FunctionHelper.askUserForFileURL(DocumentView.this,true);
396 if(sURL!=null)
397 DocumentView.this.load(sURL);
399 else
401 // save current document
402 if( sCommand.equals(COMMAND_SAVE) )
404 DocumentView.this.save();
406 else
408 // export current document to html
409 if( sCommand.equals(COMMAND_EXPORT))
411 String sURL = FunctionHelper.askUserForFileURL(DocumentView.this,false);
412 if(sURL!=null)
413 DocumentView.this.exportHTML(sURL);
415 else
417 // exit application
418 if( sCommand.equals(COMMAND_EXIT) )
420 // This will force deleting of this and
421 // all other currently opened views automatically!
422 System.exit(0);
428 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */