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 package embeddedobj.test;
23 
24 import java.awt.*;
25 import java.applet.*;
26 import java.awt.event.*;
27 import java.net.*;
28 import java.io.*;
29 import java.util.Vector;
30 
31 import javax.swing.JOptionPane;
32 import javax.swing.Timer;
33 
34 import com.sun.star.lang.XMultiServiceFactory;
35 import com.sun.star.lang.XSingleServiceFactory;
36 
37 import com.sun.star.uno.UnoRuntime;
38 import com.sun.star.uno.XInterface;
39 import com.sun.star.uno.AnyConverter;
40 import com.sun.star.uno.Type;
41 import com.sun.star.uno.Any;
42 
43 import com.sun.star.lang.XComponent;
44 
45 import com.sun.star.util.XCloseable;
46 import com.sun.star.util.XURLTransformer;
47 import com.sun.star.util.URL;
48 
49 import com.sun.star.beans.PropertyValue;
50 import com.sun.star.beans.NamedValue;
51 
52 import com.sun.star.datatransfer.DataFlavor;
53 import com.sun.star.datatransfer.XTransferable;
54 
55 import com.sun.star.container.XNameAccess;
56 
57 import com.sun.star.io.XStream;
58 import com.sun.star.io.XInputStream;
59 import com.sun.star.io.XOutputStream;
60 import com.sun.star.io.XTruncate;
61 
62 import com.sun.star.awt.XWindow;
63 import com.sun.star.awt.XBitmap;
64 
65 import com.sun.star.task.XJob;
66 
67 import com.sun.star.embed.*;
68 
69 
70 class ActionObject
71 {
72 	public byte m_nID;
73 	public String m_sParam;
74 
75 	public ActionObject()
76 	{
77 		m_nID = 0;
78 		m_sParam = null;
79 	}
80 
81 	public ActionObject( byte nID )
82 	{
83 		m_nID = nID;
84 		m_sParam = null;
85 	}
86 
87 	public ActionObject( byte nID, String sParam )
88 	{
89 		m_nID = nID;
90 		m_sParam = sParam;
91 	}
92 
93 	public ActionObject( ActionObject aObject )
94 	{
95 		m_nID = aObject.m_nID;
96 		m_sParam = aObject.m_sParam;
97 	}
98 };
99 
100 public class EmbedContApp extends Applet
101 	implements MouseListener, XEmbeddedClient, ActionListener, XJob, XInplaceClient, XWindowSupplier
102 {
103 	private XMultiServiceFactory m_xServiceFactory;
104 
105 	private final boolean m_bStoreVisRepl = false;
106 
107 	private XJob m_xMainThreadExecutor;
108 	private NamedValue[] m_pValuesForExecutor;
109 
110 	private XEmbeddedObject m_xEmbedObj;
111 	private XStorage m_xStorage;
112 	private float	 m_nXScaling;
113 	private float	 m_nYScaling;
114 	private float	 m_nXPixelSize;
115 	private float	 m_nYPixelSize;
116 
117 	private Frame m_aFrame;
118 	private Menu m_aFileMenu;
119 	private Menu m_aObjectMenu;
120 	private Toolkit m_aToolkit;
121 
122 	private Image m_aImage;
123 	private Object m_oImageLock;
124 
125 	private boolean m_bOwnFile = false;
126 
127 	private boolean m_bLinkObj = false;
128 	private String m_aLinkURI;
129 
130 	private Object m_oActionsNumberLock;
131 	private Vector m_aActionsList;
132 
133 	private Timer m_aTimer;
134 	private boolean m_bDestroyed = false;
135 
136 	private Object m_oInHandlerLock;
137 	private boolean m_bInHandler = false;
138 
139 	private XURLTransformer m_xTransformer;
140 
141 	private NativeView m_aNativeView;
142 	private XWindow m_xVCLWindow;
143 
144 	private XBitmap m_xBitmap;
145 	private BitmapPainter m_aBitmapPainter;
146 
147 // Constants
148 	private final byte DESTROY					=  1;
149 	private final byte ACTIVATE_OUTPLACE		=  2;
150 	private final byte NEW_DOCUMENT				=  3;
151 	private final byte SAVE_AS					=  4;
152 	private final byte OPEN_FILE				=  5;
153 	private final byte SAVE						=  6;
154 	private final byte NEW_OBJECT				=  7;
155 	private final byte OBJECT_FROM_FILE			=  8;
156 	private final byte LINK_FROM_FILE			=  9;
157 	private final byte CONVERT_LINK_TO_OBJECT	= 10;
158 	private final byte ACTIVATE_INPLACE			= 11;
159 	private final byte DEACTIVATE				= 12;
160 
161 // Methods
162 	public EmbedContApp( Frame aFrame, XMultiServiceFactory xServiceFactory )
163 	{
164 		m_aFrame = aFrame;
165 		m_xServiceFactory = xServiceFactory;
166 	}
167 
168 	public void init()
169 	{
170 		resize( 800, 600 );
171 		setBackground( Color.gray );
172 
173 		m_aToolkit = Toolkit.getDefaultToolkit();
174 
175 		try {
176 			Object oTransformer = m_xServiceFactory.createInstance( "com.sun.star.util.URLTransformer" );
177 			m_xTransformer = (XURLTransformer)UnoRuntime.queryInterface( XURLTransformer.class, oTransformer );
178 		} catch( Exception e ) { System.exit( 0 ); }
179 
180 		m_oActionsNumberLock = new Object();
181 		m_aActionsList = new Vector();
182 
183 		m_oInHandlerLock = new Object();
184 		m_oImageLock = new Object();
185 
186 		try {
187 			Object oJob = m_xServiceFactory.createInstance( "com.sun.star.comp.thread.MainThreadExecutor" );
188 			m_xMainThreadExecutor = (XJob)UnoRuntime.queryInterface( XJob.class, oJob );
189 		} catch( Exception e ) {}
190 
191 		if ( m_xMainThreadExecutor == null )
192 		{
193 			System.out.println( "Can't create MainThreadExecutor! The application is unusable!" );
194 			System.exit( 0 );
195 		}
196 
197 		m_nXScaling = 1;
198 		m_nYScaling = 1;
199 		m_nXPixelSize = 1;
200 		m_nYPixelSize = 1;
201 
202 		m_pValuesForExecutor = new NamedValue[1];
203 		m_pValuesForExecutor[0] = new NamedValue( "JobToExecute", (Object)this );
204 
205 		m_aTimer = new Timer( 100, this );
206 		m_aTimer.start();
207 
208 		// Get a menu bar.
209 		MenuBar aMenuBar = m_aFrame.getMenuBar();
210 		if( aMenuBar == null )
211 		{
212 			aMenuBar = new MenuBar();
213 			m_aFrame.setMenuBar( aMenuBar );
214 		}
215 
216 		// Create menus for the menu bar.
217 
218 		// File menu
219 		m_aFileMenu = new Menu( "File", true );
220 		aMenuBar.add( m_aFileMenu );
221 
222 		MenuItem aItem = new NewMenuItem();
223 		m_aFileMenu.add( aItem );
224 
225 		aItem = new OpenFileMenuItem();
226 		m_aFileMenu.add( aItem );
227 
228 		aItem = new SaveMenuItem();
229 		m_aFileMenu.add( aItem );
230 
231 		aItem = new SaveAsMenuItem();
232 		m_aFileMenu.add( aItem );
233 
234 		// Object menu
235 		m_aObjectMenu = new Menu( "Object", true );
236 		aMenuBar.add( m_aObjectMenu );
237 
238 		aItem = new NewObjectMenuItem();
239 		m_aObjectMenu.add( aItem );
240 
241 		aItem = new LoadObjectMenuItem();
242 		m_aObjectMenu.add( aItem );
243 
244 		aItem = new LinkObjectMenuItem();
245 		m_aObjectMenu.add( aItem );
246 
247 		aItem = new ConvertLinkToEmbedMenuItem();
248 		m_aObjectMenu.add( aItem );
249 
250 		// Activation menu
251 		m_aObjectMenu = new Menu( "Activation", true );
252 		aMenuBar.add( m_aObjectMenu );
253 
254 		aItem = new ActivateOutplaceMenuItem();
255 		m_aObjectMenu.add( aItem );
256 
257 		aItem = new ActivateInplaceMenuItem();
258 		m_aObjectMenu.add( aItem );
259 
260 		aItem = new DeactivateMenuItem();
261 		m_aObjectMenu.add( aItem );
262 
263 		m_aNativeView = new NativeView();
264 		m_aNativeView.resize( 800, 600 );
265 		this.add( m_aNativeView );
266 
267 		// Handle mouse clicks in our window.
268 //		addMouseListener( this );
269 	}
270 
271 	public void actionPerformed( ActionEvent evt )
272 	{
273 		synchronized( m_oInHandlerLock )
274 		{
275 			if ( m_bInHandler )
276 				return;
277 			m_bInHandler = true;
278 		}
279 
280 		synchronized( m_oActionsNumberLock )
281 		{
282 			if ( m_aActionsList.size() > 0 )
283 			{
284 				try {
285 					m_xMainThreadExecutor.execute( m_pValuesForExecutor );
286 				}
287 				catch( Exception e )
288 				{
289 					System.out.println( "Exception in actionPerformed() : " + e );
290 				}
291 			}
292 			else
293 			{
294 				synchronized( m_oInHandlerLock )
295 				{
296 					m_bInHandler = false;
297 				}
298 			}
299 		}
300 	}
301 
302 	// XWindowSupplier
303 	public XWindow getWindow()
304 	{
305 		return m_xVCLWindow;
306 	}
307 
308 	// XEmbeddedClient
309 	public void saveObject()
310 		throws com.sun.star.uno.Exception
311 	{
312 		if ( m_xEmbedObj != null )
313 		{
314 			try {
315 				XEmbedPersist xPersist = (XEmbedPersist)UnoRuntime.queryInterface( XEmbedPersist.class, m_xEmbedObj );
316 				if ( xPersist != null )
317 				{
318 					xPersist.storeOwn();
319 					generateNewImage();
320 				}
321 				else
322 					JOptionPane.showMessageDialog( m_aFrame, "No XEmbedPersist!", "Error:", JOptionPane.ERROR_MESSAGE );
323 			}
324 			catch( Exception e )
325 			{
326 				JOptionPane.showMessageDialog( m_aFrame, e, "Exception in saveObject:", JOptionPane.ERROR_MESSAGE );
327 			}
328 		}
329 
330 		generateNewImage();
331 		repaint();
332 	}
333 
334 	public void onShowWindow( boolean bVisible )
335 	{
336 		// for now nothing to do
337 	}
338 
339 	// XInplaceClient
340 	public boolean canInplaceActivate()
341 	{
342 		return true;
343 	}
344 
345 	public void onInplaceActivate()
346 	{
347 		// TODO
348 		// prepare for inplace activation
349 
350 		// REMOVE
351 		// workaround for CLIPCHILDREN problem
352 		if ( m_aBitmapPainter != null )
353 			m_aBitmapPainter.stopPainting();
354 	}
355 
356 	public void onUIActivate()
357 	{
358 		// TODO
359 		// prepare for UI activate
360 	}
361 
362 	public void onInplaceDeactivate()
363 	{
364 		// TODO
365 		// inplace deactivation is done
366 
367 		// REMOVE
368 		// workaround for CLIPCHILDREN problem
369 		if ( m_aBitmapPainter != null )
370 			m_aBitmapPainter.startPainting();
371 	}
372 
373 	public void onUIDeactivate()
374 	{
375 		// TODO
376 		// prepare for UI deactivate
377 	}
378 
379 	public XIPMainContainerWindow getTopmostWindow()
380 	{
381 		// TODO
382 		// return an implementation of XIPMainContainerWindow
383 		// mainly required for ui activation
384 		// dummy implementation is enough for inplace activation
385 
386 		return null;
387 	}
388 
389 	public XInplaceUIWindow getDocumentWindow()
390 	{
391 		// TODO
392 		// return implementation of XInplaceUIWindow
393 		// mainly required for ui activation
394 		// dummy implementation is enough for inplace activation
395 
396 		return null;
397 	}
398 
399 	public com.sun.star.awt.Rectangle getPosRect()
400 	{
401 		// provide position rectangle to the object
402 		try {
403 			// here object bitmap and scaling factor hold the size
404 			com.sun.star.awt.Size aBitmapSize = m_xBitmap.getSize();
405 			com.sun.star.awt.Size aVisSize = new com.sun.star.awt.Size(
406 											(int)( aBitmapSize.Width * m_nXScaling ),
407 											(int)( aBitmapSize.Height * m_nYScaling ) );
408 			return new com.sun.star.awt.Rectangle( 10, 10, aVisSize.Width, aVisSize.Height );
409 		}
410 		catch( Exception e )
411 		{
412 			System.out.println( "Position rectangle generation failed!" );
413 		}
414 
415 		return new com.sun.star.awt.Rectangle( 10, 10, 110, 110 );
416 	}
417 
418 	public com.sun.star.awt.Rectangle getClipRect()
419 	{
420 		// provide clip rectangle to the object
421 		// in this application position and clip rectangles are the same
422 
423 		try {
424 			// here object bitmap and scaling factor hold the size
425 			com.sun.star.awt.Size aBitmapSize = m_xBitmap.getSize();
426 			com.sun.star.awt.Size aVisSize = new com.sun.star.awt.Size(
427 											(int)( aBitmapSize.Width * m_nXScaling ),
428 											(int)( aBitmapSize.Height * m_nYScaling ) );
429 			return new com.sun.star.awt.Rectangle( 10, 10, aVisSize.Width, aVisSize.Height );
430 		}
431 		catch( Exception e )
432 		{
433 			System.out.println( "Clip rectangle generation failed!" );
434 		}
435 
436 		return new com.sun.star.awt.Rectangle( 10, 10, 110, 110 );
437 	}
438 
439 	public void translateAccelerators( com.sun.star.awt.KeyEvent[] aKeys )
440 	{
441 		// TODO
442 		// an accelerator table for object
443 		// ui activation related
444 	}
445 
446 	public void scrollObj( com.sun.star.awt.Size aOffset )
447 	{
448 		// TODO
449 		// scrolls the object to a specified offset
450 		// not mandatory for the testing application :)
451 	}
452 
453 	public void onPosRectChange( com.sun.star.awt.Rectangle aPosRect )
454 	{
455 		// object asks to change the position
456 		if ( m_xEmbedObj != null )
457 		{
458 			try {
459 				int nState = m_xEmbedObj.getCurrentState();
460 				// such a position change make sense only when object is
461 				// either inplace or ui active
462 				if ( nState == EmbedStates.EMBED_INPLACE_ACTIVE
463 			  	|| nState == EmbedStates.EMBED_UI_ACTIVE )
464 			 	{
465 					XInplaceObject xInplObj = (XInplaceObject)UnoRuntime.queryInterface( XInplaceObject.class, m_xEmbedObj );
466 			 		if ( xInplObj != null )
467 					{
468 						xInplObj.setObjectRects( aPosRect, aPosRect ); // show the whole object
469 						if ( m_aBitmapPainter != null )
470 							m_aBitmapPainter.setRect( aPosRect );
471 					}
472 					else
473 			 			System.out.println( "Why object that does not support inplace activation behave like inplace object?!" );
474 			 	}
475 			 	else
476 			 		System.out.println( "The object is not active but asks to change visual area!" );
477 			} catch( Exception e )
478 			{
479 			 	System.out.println( "Exception is thrown in onPosRectChange: " + e );
480 			}
481 		}
482 		else
483 		 	System.out.println( "Who asks to change visual area?!!" );
484 	}
485 
486 	// XJob
487 	public Object execute( NamedValue[] pValues )
488 	{
489 		for( int nInd = 0; nInd < m_aActionsList.size(); nInd++ )
490 		{
491 			ActionObject aAction = ( ActionObject ) m_aActionsList.get( nInd );
492 			if ( aAction != null )
493 			{
494 				if ( aAction.m_nID == DESTROY )
495 				{
496 					// free all resources
497 					clearObjectAndStorage();
498 					m_bDestroyed = true;
499 				}
500 				else if ( aAction.m_nID == ACTIVATE_OUTPLACE )
501 				{
502 					// activate object if exists and not active
503 					if ( m_xEmbedObj != null )
504 					{
505 						try {
506 							m_xEmbedObj.changeState( EmbedStates.EMBED_ACTIVE );
507 						}
508 						catch( Exception ex )
509 						{
510 							System.out.println( "Exception on mouse click" + ex );
511 						}
512 					}
513 				}
514 				else if ( aAction.m_nID == NEW_DOCUMENT )
515 				{
516 					// clear everything
517 					clearObjectAndStorage();
518 
519 					repaint();
520 				}
521 				else if ( aAction.m_nID == SAVE_AS )
522 				{
523 					// open SaveAs dialog and store
524 
525 					if ( m_xStorage != null && m_xEmbedObj != null )
526 					{
527 						try {
528 							/*
529 								if ( m_bLinkObj )
530 									storeLinkAsFileURI( aFileURI );
531 								else
532 							*/
533 							saveObjectAsFileURI( aAction.m_sParam );
534 						}
535 						catch( Exception ex )
536 						{
537 							System.out.println( "Exception in SaveAsMenuItem: " + ex );
538 						}
539 					}
540 				}
541 				else if ( aAction.m_nID == OPEN_FILE )
542 				{
543 					// clear everything
544 					clearObjectAndStorage();
545 
546 					// load from specified file
547 					loadFileURI( aAction.m_sParam );
548 
549 					if ( m_xEmbedObj != null )
550 					{
551 						try {
552 							m_xEmbedObj.setClientSite( this );
553 						}
554 						catch( Exception ex )
555 						{
556 							System.out.println( "Exception in OpenFileMenuItem: " + ex );
557 						}
558 					}
559 
560 					generateNewImage();
561 					repaint();
562 				}
563 				else if ( aAction.m_nID == SAVE )
564 				{
565 					if ( m_xStorage != null && m_xEmbedObj != null )
566 					{
567 						// if has persistence store there
568 						// if not it is and error, SaveAs had to be used
569 
570 						if ( m_bOwnFile )
571 						{
572 							if ( m_xStorage != null )
573 							{
574 								try {
575 									saveObject();
576 
577 									if ( m_bLinkObj )
578 										storeLinkToStorage();
579 
580 									XTransactedObject xTransact = (XTransactedObject)UnoRuntime.queryInterface( XTransactedObject.class,
581 																												m_xStorage );
582 									if ( xTransact != null )
583 										xTransact.commit();
584 								}
585 								catch( Exception ex )
586 								{
587 									System.out.println( "Exception during save operation in SaveMenuItem:" + ex );
588 								}
589 							}
590 							else
591 							{
592 								System.out.println( "No storage for owned file!" );
593 							}
594 						}
595 						else
596 						{
597 							System.out.println( "No owned file!" );
598 						}
599 					}
600 				}
601 				else if ( aAction.m_nID == NEW_OBJECT )
602 				{
603 					// remove current object an init a new one
604 					clearObjectAndStorage();
605 
606 					if ( aAction.m_sParam != null )
607 					{
608 						m_xStorage = createTempStorage();
609 
610 						if ( m_xStorage != null )
611 							m_xEmbedObj = createEmbedObject( aAction.m_sParam );
612 						else
613 							System.out.println( "Can't create temporary storage!" );
614 
615 						if ( m_xEmbedObj != null )
616 						{
617 							try {
618 								m_xEmbedObj.setClientSite( this );
619 							}
620 							catch( Exception ex )
621 							{
622 								System.out.println( "Exception in NewObjectMenuItem:" + ex );
623 							}
624 						}
625 					}
626 
627 					generateNewImage();
628 					repaint();
629 				}
630 				else if ( aAction.m_nID == OBJECT_FROM_FILE )
631 				{
632 					// first remove current object
633 					clearObjectAndStorage();
634 
635 					// create object from specified file
636 					m_xStorage = createTempStorage();
637 
638 					if ( m_xStorage != null )
639 						m_xEmbedObj = loadEmbedObject( aAction.m_sParam );
640 
641 					if ( m_xEmbedObj != null )
642 					{
643 						try {
644 							m_xEmbedObj.setClientSite( this );
645 						}
646 						catch( Exception ex )
647 						{
648 							System.out.println( "Exception in LoadObjectMenuItem: " + ex );
649 						}
650 					}
651 
652 					generateNewImage();
653 					repaint();
654 				}
655 				else if ( aAction.m_nID == LINK_FROM_FILE )
656 				{
657 					// first remove current object
658 					clearObjectAndStorage();
659 
660 					m_xStorage = createTempStorage();
661 
662 					// create object from specified file
663 					m_xEmbedObj = createLinkObject( aAction.m_sParam );
664 
665 					if ( m_xEmbedObj != null )
666 					{
667 						m_aLinkURI = aAction.m_sParam;
668 						m_bLinkObj = true;
669 
670 						try {
671 							m_xEmbedObj.setClientSite( this );
672 						}
673 						catch( Exception ex )
674 						{
675 							System.out.println( "Exception in LinkObjectMenuItem:" + ex );
676 						}
677 					}
678 
679 					generateNewImage();
680 					repaint();
681 				}
682 				else if ( aAction.m_nID == CONVERT_LINK_TO_OBJECT )
683 				{
684 					if ( !m_bLinkObj )
685 					{
686 						System.out.println( "The object is not a link!" );
687 						continue;
688 					}
689 
690 					if ( m_xEmbedObj != null )
691 					{
692 						if ( m_xStorage != null )
693 						{
694 							try {
695 								XNameAccess xNameAccess = (XNameAccess)UnoRuntime.queryInterface( XNameAccess.class,
696 																								m_xStorage );
697 								if ( xNameAccess != null && xNameAccess.hasByName( "LinkName" ) )
698 									m_xStorage.removeElement( "LinkName" );
699 
700 								XLinkageSupport xLinkage = (XLinkageSupport)UnoRuntime.queryInterface( XLinkageSupport.class,
701 																										m_xEmbedObj );
702 								if ( xLinkage != null )
703 								{
704 									xLinkage.breakLink( m_xStorage, "EmbedSub" );
705 									m_bLinkObj = false;
706 									m_aLinkURI = null;
707 								}
708 								else
709 									System.out.println( "No XLinkageSupport in ConvertLink... !" );
710 							}
711 							catch( Exception e1 )
712 							{
713 								System.out.println( "Exception in ConvertLinkToEmbed:try 1 :" + e1 );
714 							}
715 						}
716 					}
717 				}
718 				else if ( aAction.m_nID == ACTIVATE_INPLACE )
719 				{
720 					// activate object
721 					if ( m_xEmbedObj != null )
722 					{
723 						// in general it is better to check acceptable states
724 						try {
725 							m_xEmbedObj.changeState( EmbedStates.EMBED_INPLACE_ACTIVE );
726 						}
727 						catch( Exception ex )
728 						{
729 							System.out.println( "Exception on inplace activation " + ex );
730 						}
731 					}
732 				}
733 				else if ( aAction.m_nID == DEACTIVATE )
734 				{
735 					// activate object
736 
737 					if ( m_xEmbedObj != null )
738 					{
739 						int nOldState = -1;
740 						try {
741 							nOldState = m_xEmbedObj.getCurrentState();
742 						} catch( Exception e )
743 						{}
744 
745 						if ( nOldState == EmbedStates.EMBED_ACTIVE
746 						  || nOldState == EmbedStates.EMBED_INPLACE_ACTIVE
747 						  || nOldState == EmbedStates.EMBED_UI_ACTIVE )
748 						{
749 							try {
750 								m_xEmbedObj.changeState( EmbedStates.EMBED_RUNNING );
751 							}
752 							catch( Exception ex )
753 							{
754 								System.out.println( "Exception on inplace activation " + ex );
755 							}
756 						}
757 						else
758 						{
759 							System.out.println( "Deactivation of nonactive object!" );
760 						}
761 					}
762 				}
763 				else
764 				{
765 					System.out.println( "Unknoun action is requested: " + aAction.m_nID + "\n" );
766 				}
767 			}
768 		}
769 
770 		m_aActionsList.clear();
771 
772 		synchronized( m_oInHandlerLock )
773 		{
774 			m_bInHandler = false;
775 		}
776 
777 		return Any.VOID;
778 	}
779 
780 	public void actionRegister( byte nActionID, String sParam )
781 	{
782 		synchronized( m_oActionsNumberLock )
783 		{
784 			int nSize = m_aActionsList.size();
785 			if ( nSize < 199 )
786 			{
787 				if ( nSize == 0 )
788 					m_aActionsList.add( new ActionObject( nActionID, sParam ) );
789 				else
790 				{
791 					ActionObject aAction = ( ActionObject ) m_aActionsList.get( nSize - 1 );
792 					if ( aAction != null && aAction.m_nID != DESTROY )
793 						m_aActionsList.add( new ActionObject( nActionID, sParam ) );
794 				}
795 			}
796 		}
797 	}
798 
799 	public void SaveAsOperation()
800 	{
801 		if ( m_xStorage != null && m_xEmbedObj != null )
802 		{
803 			FileDialog aFileDialog = new FileDialog( m_aFrame, "SaveAs", FileDialog.SAVE );
804 			aFileDialog.show();
805 			if ( aFileDialog.getFile() != null )
806 			{
807 				String aFileName = aFileDialog.getDirectory() + aFileDialog.getFile();
808 				File aFile = new File( aFileName );
809 				if ( aFile != null )
810 				{
811 					// create object from specified file
812 					String aFileURI = getValidURL( aFile.toURI().toASCIIString() );
813 					actionRegister( SAVE_AS, aFileURI );
814 				}
815 			}
816 		}
817 		else
818 			JOptionPane.showMessageDialog( m_aFrame, "No document is embedded!", "Error:", JOptionPane.ERROR_MESSAGE );
819 
820 	}
821 
822 	public void destroy()
823 	{
824 		// redirect the call through the timer and call super.destroy();
825 		actionRegister( DESTROY, null );
826 
827 		for ( int i = 0; i < 3 && !m_bDestroyed; i++ )
828 		{
829 			try {
830 				Thread.sleep( 200 );
831 			} catch ( Exception e )
832 			{}
833 		}
834 
835 		if ( !m_bDestroyed )
836 			System.out.println( "The object application can not exit correctly!" );
837 
838 		m_aTimer.stop();
839 
840 		super.destroy();
841 	}
842 
843 	public void update( Graphics g )
844 	{
845 		paint( g );
846 	}
847 
848 	public void paint( Graphics g )
849 	{
850 		super.paint( g );
851 
852 		// m_aNativeView.paint( g );
853 
854 		createVclWindow();
855 	}
856 
857 	public void createVclWindow()
858 	{
859 		synchronized( m_oImageLock )
860 		{
861 			if ( m_xVCLWindow == null && m_xServiceFactory != null && m_xEmbedObj != null && m_xBitmap != null )
862 			{
863 				java.awt.Rectangle aBounds = getBounds();
864 				m_xVCLWindow = WindowHelper.createWindow( m_xServiceFactory, m_aNativeView, aBounds );
865 				m_xVCLWindow.setVisible( true );
866 
867 				com.sun.star.awt.Size aBitmapSize = new com.sun.star.awt.Size( 200, 100 );
868 
869 				XVisualObject xVisObj = (XVisualObject)UnoRuntime.queryInterface( XVisualObject.class, m_xEmbedObj );
870 				try {
871 					com.sun.star.awt.Size aVisSize = xVisObj.getVisAreaSize( Aspects.MSASPECT_CONTENT );
872 					m_nXPixelSize = aVisSize.Width / aBitmapSize.Width;
873 					m_nYPixelSize = aVisSize.Height / aBitmapSize.Height;
874 				}
875 				catch( Exception e )
876 				{
877 				}
878 
879 				if ( m_xBitmap != null )
880 				 	aBitmapSize = m_xBitmap.getSize();
881 
882 				System.out.println( "The visual area is Width = " + aBitmapSize.Width + "; Height = " + aBitmapSize.Height );
883 
884 				com.sun.star.awt.Rectangle aRect = new com.sun.star.awt.Rectangle(
885 														10,
886 														10,
887 														Math.min( (int)aBounds.getWidth() - 20, aBitmapSize.Width ),
888 														Math.min( (int)aBounds.getHeight() - 20, aBitmapSize.Height ) );
889 
890 				m_aBitmapPainter = new BitmapPainter( m_xMainThreadExecutor, m_xVCLWindow, m_xBitmap, aRect );
891 			}
892 		}
893 	}
894 
895 	public void generateNewImage()
896 	{
897 		if ( m_xEmbedObj != null )
898 		{
899 			try {
900 				int nOldState = m_xEmbedObj.getCurrentState();
901 				int nState = nOldState;
902 				if ( nOldState == EmbedStates.EMBED_LOADED )
903 				{
904 					m_xEmbedObj.changeState( EmbedStates.EMBED_RUNNING );
905 					nState = EmbedStates.EMBED_RUNNING;
906 				}
907 
908 				if ( nState == EmbedStates.EMBED_UI_ACTIVE || nState == EmbedStates.EMBED_INPLACE_ACTIVE
909 				  || nState == EmbedStates.EMBED_ACTIVE || nState == EmbedStates.EMBED_RUNNING )
910 				{
911 					XComponentSupplier xCompProv = (XComponentSupplier)UnoRuntime.queryInterface(
912 																					XComponentSupplier.class,
913 																					m_xEmbedObj );
914 					if ( xCompProv != null )
915 					{
916 						XCloseable xCloseable = xCompProv.getComponent();
917 						XTransferable xTransfer = (XTransferable)UnoRuntime.queryInterface(
918 																					XTransferable.class,
919 																					xCloseable );
920 						if ( xTransfer != null )
921 						{
922 							DataFlavor aFlavor = new DataFlavor();
923 							aFlavor.MimeType = "application/x-openoffice;windows_formatname=\"Bitmap\"";
924 							aFlavor.HumanPresentableName = "Bitmap";
925 							aFlavor.DataType = new Type( byte[].class );
926 
927 							Object aAny = xTransfer.getTransferData( aFlavor );
928 							if ( aAny != null && AnyConverter.isArray( aAny ) )
929 							{
930 								synchronized( m_oImageLock )
931 								{
932 									m_xBitmap = WindowHelper.getVCLBitmapFromBytes( m_xServiceFactory, aAny );
933 									if ( m_aBitmapPainter != null )
934 									{
935 										m_aBitmapPainter.setBitmap( m_xBitmap );
936 
937 										if ( m_xBitmap != null )
938 										{
939 											try {
940 												com.sun.star.awt.Size aBitmapSize = m_xBitmap.getSize();
941 												com.sun.star.awt.Size aVisSize = new com.sun.star.awt.Size(
942 																				(int)( aBitmapSize.Width * m_nXScaling ),
943 																				(int)( aBitmapSize.Height * m_nYScaling ) );
944 												m_aBitmapPainter.setSize( aVisSize );
945 											}
946 											catch( Exception e )
947 											{
948 											}
949 										}
950 									}
951 								}
952 							}
953 						}
954 						else
955 							System.out.println( "paint() : can not get XTransferable for the component!\n" );
956 					}
957 					else
958 						System.out.println( "paint() : XComponentSupplier is not implemented!\n" );
959 				}
960 			}
961 			catch( com.sun.star.uno.Exception e )
962 			{
963 				// dialogs should not be used in paint()
964 				System.out.println( "Exception in paint(): " + e );
965 			}
966 		}
967 	}
968 
969 	public void mouseClicked( MouseEvent e )
970 	{
971 		if( e.getModifiers() == InputEvent.BUTTON1_MASK )
972 		{
973 			actionRegister( ACTIVATE_OUTPLACE, null );
974 		}
975 	}
976 
977 	public void mousePressed( MouseEvent e ){};
978 	public void mouseEntered( MouseEvent e ){};
979 	public void mouseExited( MouseEvent e ){};
980 	public void mouseReleased( MouseEvent e ){};
981 
982 	// classes
983 	class NewMenuItem extends MenuItem implements ActionListener // Menu New
984 	{
985 		public NewMenuItem()
986 		{
987 			super( "New", new MenuShortcut( KeyEvent.VK_A ));
988 			addActionListener( this );
989 		}
990 
991 		public void actionPerformed( ActionEvent e )
992 		{
993 			actionRegister( NEW_DOCUMENT, null );
994 		}
995 	}
996 
997 	class SaveAsMenuItem extends MenuItem implements ActionListener // Menu SaveAs...
998 	{
999 		public SaveAsMenuItem()
1000 		{
1001 			super( "SaveAs..." );
1002 			addActionListener( this );
1003 		}
1004 
1005 		public void actionPerformed( ActionEvent e )
1006 		{
1007 			// open SaveAs dialog and store
1008 
1009 			SaveAsOperation();
1010 		}
1011 	}
1012 
1013 	class OpenFileMenuItem extends MenuItem implements ActionListener // Menu Open
1014 	{
1015 		public OpenFileMenuItem()
1016 		{
1017 			super( "Open", new MenuShortcut( KeyEvent.VK_C ));
1018 			addActionListener( this );
1019 		}
1020 
1021 		public void actionPerformed( ActionEvent e )
1022 		{
1023 			// open OpenFile dialog and load doc
1024 			FileDialog aFileDialog = new FileDialog( m_aFrame, "Open" );
1025 			aFileDialog.show();
1026 			if ( aFileDialog.getFile() != null )
1027 			{
1028 				String aFileName = aFileDialog.getDirectory() + aFileDialog.getFile();
1029 				File aFile = new File( aFileName );
1030 				if ( aFile != null )
1031 				{
1032 					// create object from specified file
1033 					String aFileURI = getValidURL( aFile.toURI().toASCIIString() );
1034 					actionRegister( OPEN_FILE, aFileURI );
1035 				}
1036 			}
1037 		}
1038 	}
1039 
1040 	class SaveMenuItem extends MenuItem implements ActionListener // Menu Save
1041 	{
1042 		public SaveMenuItem()
1043 		{
1044 			super( "Save", new MenuShortcut( KeyEvent.VK_D ));
1045 			addActionListener( this );
1046 		}
1047 
1048 		public void actionPerformed( ActionEvent e )
1049 		{
1050 			// if has persistence store there
1051 			// if not open SaveAs dialog and store
1052 			if ( m_xStorage != null && m_xEmbedObj != null )
1053 			{
1054 				if ( m_bOwnFile )
1055 				{
1056 					if ( m_xStorage == null )
1057 					{
1058 						JOptionPane.showMessageDialog( m_aFrame,
1059 														"No storage for oned file!",
1060 														"Error:",
1061 														JOptionPane.ERROR_MESSAGE );
1062 
1063 						return;
1064 					}
1065 
1066 					actionRegister( SAVE, null );
1067 				}
1068 				else
1069 				{
1070 					SaveAsOperation();
1071 				}
1072 			}
1073 			else
1074 				JOptionPane.showMessageDialog( m_aFrame, "No document is embedded!", "Error:", JOptionPane.ERROR_MESSAGE );
1075 		}
1076 	}
1077 
1078 	class NewObjectMenuItem extends MenuItem implements ActionListener // Menu NewObject
1079 	{
1080 		public NewObjectMenuItem()
1081 		{
1082 			super( "Create", new MenuShortcut( KeyEvent.VK_N ));
1083 			addActionListener( this );
1084 		}
1085 
1086 		public void actionPerformed( ActionEvent e )
1087 		{
1088 			Object[] possibleValues = { "com.sun.star.comp.Writer.TextDocument",
1089 										"com.sun.star.comp.Writer.GlobalDocument",
1090 										"com.sun.star.comp.Writer.WebDocument",
1091 										"com.sun.star.comp.Calc.SpreadsheetDocument",
1092 										"com.sun.star.comp.Draw.PresentationDocument",
1093 										"com.sun.star.comp.Draw.DrawingDocument",
1094 										"com.sun.star.comp.Math.FormulaDocument",
1095 										"BitmapImage" };
1096 
1097 			String selectedValue = (String)JOptionPane.showInputDialog( null, "DocumentType", "Select",
1098        																	JOptionPane.INFORMATION_MESSAGE, null,
1099        																	possibleValues, possibleValues[0] );
1100 
1101 			actionRegister( NEW_OBJECT, selectedValue );
1102 		}
1103 	}
1104 
1105 	class LoadObjectMenuItem extends MenuItem implements ActionListener // Menu LoadObject
1106 	{
1107 		public LoadObjectMenuItem()
1108 		{
1109 			super( "Load from file", new MenuShortcut( KeyEvent.VK_L ));
1110 			addActionListener( this );
1111 		}
1112 
1113 		public void actionPerformed( ActionEvent e )
1114 		{
1115 			// open OpenFile dialog and load doc
1116 			FileDialog aFileDialog = new FileDialog( m_aFrame, "Select sources to use for object init" );
1117 			aFileDialog.show();
1118 			if ( aFileDialog.getFile() != null )
1119 			{
1120 				String aFileName = aFileDialog.getDirectory() + aFileDialog.getFile();
1121 				File aFile = new File( aFileName );
1122 				if ( aFile != null )
1123 				{
1124 					// create object from specified file
1125 					String aFileURI = getValidURL( aFile.toURI().toASCIIString() );
1126 					actionRegister( OBJECT_FROM_FILE, aFileURI );
1127 				}
1128 			}
1129 		}
1130 	}
1131 
1132 	class LinkObjectMenuItem extends MenuItem implements ActionListener // Menu LinkObject
1133 	{
1134 		public LinkObjectMenuItem()
1135 		{
1136 			super( "Create link", new MenuShortcut( KeyEvent.VK_M ));
1137 			addActionListener( this );
1138 		}
1139 
1140 		public void actionPerformed( ActionEvent e )
1141 		{
1142 			// open OpenFile dialog and load doc
1143 			FileDialog aFileDialog = new FileDialog( m_aFrame, "Select sources to use for object init" );
1144 			aFileDialog.show();
1145 			if ( aFileDialog.getFile() != null )
1146 			{
1147 				String aFileName = aFileDialog.getDirectory() + aFileDialog.getFile();
1148 				File aFile = new File( aFileName );
1149 				if ( aFile != null )
1150 				{
1151 					// create object from specified file
1152 					String aFileURI = getValidURL( aFile.toURI().toASCIIString() );
1153 					actionRegister( LINK_FROM_FILE, aFileURI );
1154 				}
1155 			}
1156 		}
1157 	}
1158 
1159 	class ConvertLinkToEmbedMenuItem extends MenuItem implements ActionListener // Menu LinkObject
1160 	{
1161 		public ConvertLinkToEmbedMenuItem()
1162 		{
1163 			super( "Convert link to embed", new MenuShortcut( KeyEvent.VK_M ));
1164 			addActionListener( this );
1165 		}
1166 
1167 		public void actionPerformed( ActionEvent e )
1168 		{
1169 			actionRegister( CONVERT_LINK_TO_OBJECT, null );
1170 		}
1171 	}
1172 
1173 	class ActivateOutplaceMenuItem extends MenuItem implements ActionListener // Menu ActiveteOutplace
1174 	{
1175 		public ActivateOutplaceMenuItem()
1176 		{
1177 			super( "Activate outplace", new MenuShortcut( KeyEvent.VK_A ));
1178 			addActionListener( this );
1179 		}
1180 
1181 		public void actionPerformed( ActionEvent e )
1182 		{
1183 			actionRegister( ACTIVATE_OUTPLACE, null );
1184 		}
1185 	}
1186 
1187 	class ActivateInplaceMenuItem extends MenuItem implements ActionListener // Menu ActivateInplace
1188 	{
1189 		public ActivateInplaceMenuItem()
1190 		{
1191 			super( "Activate inplace", new MenuShortcut( KeyEvent.VK_I ));
1192 			addActionListener( this );
1193 		}
1194 
1195 		public void actionPerformed( ActionEvent e )
1196 		{
1197 			actionRegister( ACTIVATE_INPLACE, null );
1198 		}
1199 	}
1200 
1201 	class DeactivateMenuItem extends MenuItem implements ActionListener // Menu Deactivate
1202 	{
1203 		public DeactivateMenuItem()
1204 		{
1205 			super( "Deactivate", new MenuShortcut( KeyEvent.VK_D ));
1206 			addActionListener( this );
1207 		}
1208 
1209 		public void actionPerformed( ActionEvent e )
1210 		{
1211 			actionRegister( DEACTIVATE, null );
1212 		}
1213 	}
1214 
1215 	// Helper methods
1216 	public XEmbeddedObject createEmbedObject( String aServiceName )
1217 	{
1218 		XEmbeddedObject xEmbObj = null;
1219 		byte[] pClassID = new byte[16];
1220 
1221 		if ( aServiceName.equals( "com.sun.star.comp.Writer.TextDocument" ) )
1222 		{
1223 			int[] pTempClassID = { 0x8B, 0xC6, 0xB1, 0x65, 0xB1, 0xB2, 0x4E, 0xDD,
1224 									0xAA, 0x47, 0xDA, 0xE2, 0xEE, 0x68, 0x9D, 0xD6 };
1225 			for ( int ind = 0; ind < 16; ind++ )
1226 				pClassID[ind] = (byte)pTempClassID[ind];
1227 		}
1228 		else if ( aServiceName.equals( "com.sun.star.comp.Writer.GlobalDocument" ) )
1229 		{
1230 			int[] pTempClassID = { 0xB2, 0x1A, 0x0A, 0x7C, 0xE4, 0x03, 0x41, 0xFE,
1231 									0x95, 0x62, 0xBD, 0x13, 0xEA, 0x6F, 0x15, 0xA0 };
1232 			for ( int ind = 0; ind < 16; ind++ )
1233 				pClassID[ind] = (byte)pTempClassID[ind];
1234 		}
1235 		else if ( aServiceName.equals( "com.sun.star.comp.Writer.WebDocument" ) )
1236 		{
1237 			int[] pTempClassID = { 0xA8, 0xBB, 0xA6, 0x0C, 0x7C, 0x60, 0x45, 0x50,
1238 									0x91, 0xCE, 0x39, 0xC3, 0x90, 0x3F, 0xAC, 0x5E };
1239 			for ( int ind = 0; ind < 16; ind++ )
1240 				pClassID[ind] = (byte)pTempClassID[ind];
1241 		}
1242 		else if ( aServiceName.equals( "com.sun.star.comp.Calc.SpreadsheetDocument" ) )
1243 		{
1244 			int[] pTempClassID = { 0x47, 0xBB, 0xB4, 0xCB, 0xCE, 0x4C, 0x4E, 0x80,
1245 									0xA5, 0x91, 0x42, 0xD9, 0xAE, 0x74, 0x95, 0x0F };
1246 			for ( int ind = 0; ind < 16; ind++ )
1247 				pClassID[ind] = (byte)pTempClassID[ind];
1248 		}
1249 		else if ( aServiceName.equals( "com.sun.star.comp.Draw.PresentationDocument" ) )
1250 		{
1251 			int[] pTempClassID = { 0x91, 0x76, 0xE4, 0x8A, 0x63, 0x7A, 0x4D, 0x1F,
1252 									0x80, 0x3B, 0x99, 0xD9, 0xBF, 0xAC, 0x10, 0x47 };
1253 			for ( int ind = 0; ind < 16; ind++ )
1254 				pClassID[ind] = (byte)pTempClassID[ind];
1255 		}
1256 		else if ( aServiceName.equals( "com.sun.star.comp.Draw.DrawingDocument" ) )
1257 		{
1258 			int[] pTempClassID = { 0x4B, 0xAB, 0x89, 0x70, 0x8A, 0x3B, 0x45, 0xB3,
1259 									0x99, 0x1C, 0xCB, 0xEE, 0xAC, 0x6B, 0xD5, 0xE3 };
1260 			for ( int ind = 0; ind < 16; ind++ )
1261 				pClassID[ind] = (byte)pTempClassID[ind];
1262 		}
1263 		else if ( aServiceName.equals( "com.sun.star.comp.Math.FormulaDocument" ) )
1264 		{
1265 			int[] pTempClassID = { 0x07, 0x8B, 0x7A, 0xBA, 0x54, 0xFC, 0x45, 0x7F,
1266 									0x85, 0x51, 0x61, 0x47, 0xE7, 0x76, 0xA9, 0x97 };
1267 			for ( int ind = 0; ind < 16; ind++ )
1268 				pClassID[ind] = (byte)pTempClassID[ind];
1269 		}
1270 		else if ( aServiceName.equals( "BitmapImage" ) )
1271 		{
1272 			int[] pTempClassID = { 0xD3, 0xE3, 0x4B, 0x21, 0x9D, 0x75, 0x10, 0x1A,
1273 									0x8C, 0x3D, 0x00, 0xAA, 0x00, 0x1A, 0x16, 0x52 };
1274 			for ( int ind = 0; ind < 16; ind++ )
1275 				pClassID[ind] = (byte)pTempClassID[ind];
1276 		}
1277 
1278 		if ( pClassID != null )
1279 		{
1280 			// create embedded object based on the class ID
1281 			try {
1282 				Object oEmbedCreator = m_xServiceFactory.createInstance( "com.sun.star.embed.EmbeddedObjectCreator" );
1283 				XEmbedObjectCreator xEmbedCreator = (XEmbedObjectCreator)UnoRuntime.queryInterface(
1284 																						XEmbedObjectCreator.class,
1285 																						oEmbedCreator );
1286 				if ( xEmbedCreator != null )
1287 				{
1288 					Object oEmbObj = xEmbedCreator.createInstanceInitNew( pClassID,
1289 																		"Dummy name",
1290 																		m_xStorage,
1291 																		"EmbedSub",
1292 																		new PropertyValue[0] );
1293 					xEmbObj = (XEmbeddedObject)UnoRuntime.queryInterface( XEmbeddedObject.class, oEmbObj );
1294 				}
1295 				else
1296 					JOptionPane.showMessageDialog( m_aFrame,
1297 												   "Can't create EmbedCreator!",
1298 												   "Error:",
1299 												   JOptionPane.ERROR_MESSAGE );
1300 			}
1301 			catch( Exception e )
1302 			{
1303 				JOptionPane.showMessageDialog( m_aFrame, e, "Exception in createInstanceInitNew():", JOptionPane.ERROR_MESSAGE );
1304 			}
1305 		}
1306 		else
1307 			JOptionPane.showMessageDialog( m_aFrame, "Can't retrieve class ID!", "Error:", JOptionPane.ERROR_MESSAGE );
1308 
1309 		return xEmbObj;
1310 	}
1311 
1312 	public XEmbeddedObject createLinkObject( String aLinkURL )
1313 	{
1314 		XEmbeddedObject xEmbObj = null;
1315 
1316 		try {
1317 			Object oLinkCreator = m_xServiceFactory.createInstance( "com.sun.star.embed.EmbeddedObjectCreator" );
1318 			XLinkCreator xLinkCreator = (XLinkCreator)UnoRuntime.queryInterface(
1319 																					XLinkCreator.class,
1320 																					oLinkCreator );
1321 			if ( xLinkCreator != null )
1322 			{
1323 				PropertyValue[] aMedDescr = { new PropertyValue(), new PropertyValue() };
1324 				aMedDescr[0].Name = "URL";
1325 				aMedDescr[0].Value = (Object) aLinkURL;
1326 				aMedDescr[1].Name = "ReadOnly";
1327 				aMedDescr[1].Value = (Object) new Boolean( false );
1328 				Object oEmbObj = xLinkCreator.createInstanceLink( m_xStorage, "EmbedSub", aMedDescr, new PropertyValue[0] );
1329 				xEmbObj = (XEmbeddedObject)UnoRuntime.queryInterface( XEmbeddedObject.class, oEmbObj );
1330 			}
1331 			else
1332 				JOptionPane.showMessageDialog( m_aFrame,
1333 											   "Can't create LinkCreator!",
1334 											   "Error:",
1335 											   JOptionPane.ERROR_MESSAGE );
1336 		}
1337 		catch( Exception e )
1338 		{
1339 			JOptionPane.showMessageDialog( m_aFrame, e, "Exception in createLinkObject():", JOptionPane.ERROR_MESSAGE );
1340 		}
1341 
1342 
1343 		return xEmbObj;
1344 	}
1345 
1346 
1347 	public XEmbeddedObject loadEmbedObject( String aFileURI )
1348 	{
1349 		XEmbeddedObject xEmbObj = null;
1350 		try {
1351 			Object oEmbedCreator = m_xServiceFactory.createInstance( "com.sun.star.embed.EmbeddedObjectCreator" );
1352 			XEmbedObjectCreator xEmbedCreator = (XEmbedObjectCreator)UnoRuntime.queryInterface(
1353 																					XEmbedObjectCreator.class,
1354 																					oEmbedCreator );
1355 			if ( xEmbedCreator != null )
1356 			{
1357 				PropertyValue[] aMedDescr = { new PropertyValue(), new PropertyValue() };
1358 				aMedDescr[0].Name = "URL";
1359 				aMedDescr[0].Value = (Object) aFileURI;
1360 				aMedDescr[1].Name = "ReadOnly";
1361 				aMedDescr[1].Value = (Object) new Boolean( false );
1362 				Object oEmbObj = xEmbedCreator.createInstanceInitFromMediaDescriptor( m_xStorage,
1363 																					"EmbedSub",
1364 																					aMedDescr,
1365 																					new PropertyValue[0] );
1366 				xEmbObj = (XEmbeddedObject)UnoRuntime.queryInterface( XEmbeddedObject.class, oEmbObj );
1367 			}
1368 			else
1369 				JOptionPane.showMessageDialog( m_aFrame,
1370 											   "Can't create EmbedFactory!",
1371 											   "Error:",
1372 											   JOptionPane.ERROR_MESSAGE );
1373 		}
1374 		catch( Exception e )
1375 		{
1376 			JOptionPane.showMessageDialog( m_aFrame, e, "Exception in loadEmbedObject():", JOptionPane.ERROR_MESSAGE );
1377 		}
1378 
1379 		return xEmbObj;
1380 	}
1381 
1382 	public void clearObjectAndStorage()
1383 	{
1384 		synchronized( m_oImageLock )
1385 		{
1386 			m_aImage = null;
1387 		}
1388 
1389 		m_nXScaling = 1;
1390 		m_nYScaling = 1;
1391 		m_nXPixelSize = 1;
1392 		m_nYPixelSize = 1;
1393 
1394 		m_bOwnFile = false;
1395 
1396 		m_aLinkURI = null;
1397 		m_bLinkObj = false;
1398 
1399 		if ( m_xEmbedObj != null )
1400 		{
1401 			try {
1402 				XCloseable xClose = (XCloseable)UnoRuntime.queryInterface( XCloseable.class, m_xEmbedObj );
1403 				if ( xClose != null )
1404 					xClose.close( true );
1405 			}
1406 			catch ( Exception ex )
1407 			{}
1408 			m_xEmbedObj = null;
1409 		}
1410 
1411 		if ( m_xStorage != null )
1412 		{
1413 			try {
1414 				XComponent xComponent = (XComponent)UnoRuntime.queryInterface( XComponent.class, m_xStorage );
1415 				if ( xComponent != null )
1416 					xComponent.dispose();
1417 			}
1418 			catch ( Exception ex )
1419 			{}
1420 			m_xStorage = null;
1421 		}
1422 	}
1423 
1424 	public XStorage createTempStorage()
1425 	{
1426 		XStorage xTempStorage = null;
1427 
1428 		try {
1429 			Object oStorageFactory = m_xServiceFactory.createInstance( "com.sun.star.embed.StorageFactory" );
1430 			XSingleServiceFactory xStorageFactory = (XSingleServiceFactory)UnoRuntime.queryInterface(
1431 																						XSingleServiceFactory.class,
1432 																						oStorageFactory );
1433 			if ( xStorageFactory != null )
1434 			{
1435 				Object oStorage = xStorageFactory.createInstance();
1436 				xTempStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oStorage );
1437 			}
1438 			else
1439 				JOptionPane.showMessageDialog( m_aFrame,
1440 												"Can't create StorageFactory!",
1441 												"Error:",
1442 												JOptionPane.ERROR_MESSAGE );
1443 		}
1444 		catch( Exception e )
1445 		{
1446 			JOptionPane.showMessageDialog( m_aFrame, e, "Exception in createTempStorage():", JOptionPane.ERROR_MESSAGE );
1447 		}
1448 
1449 		return xTempStorage;
1450 	}
1451 
1452 	public void saveObjectAsFileURI( String aFileURI )
1453 	{
1454 		try {
1455 			Object oStorageFactory = m_xServiceFactory.createInstance( "com.sun.star.embed.StorageFactory" );
1456 			XSingleServiceFactory xStorageFactory = (XSingleServiceFactory)UnoRuntime.queryInterface(
1457 																						XSingleServiceFactory.class,
1458 																						oStorageFactory );
1459 			if ( xStorageFactory != null )
1460 			{
1461 				XEmbedPersist xPersist = (XEmbedPersist)UnoRuntime.queryInterface( XEmbedPersist.class, m_xEmbedObj );
1462 				if ( xPersist != null )
1463 				{
1464 					Object aArgs[] = new Object[2];
1465 					aArgs[0] = aFileURI;
1466 					aArgs[1] = new Integer( ElementModes.ELEMENT_READWRITE );
1467 
1468 					Object oStorage = xStorageFactory.createInstanceWithArguments( aArgs );
1469 					XStorage xTargetStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oStorage );
1470 
1471 					PropertyValue aProps[] = { new PropertyValue() };
1472 					aProps[0].Name = "StoreVisualReplacement";
1473 					aProps[0].Value = new Boolean( m_bStoreVisRepl );
1474 
1475 					xPersist.storeAsEntry( xTargetStorage, "EmbedSub", new PropertyValue[0], aProps );
1476 					xPersist.saveCompleted( true );
1477 
1478 					// the object must be already based on new storage
1479 					XComponent xComponent = (XComponent)UnoRuntime.queryInterface( XComponent.class, m_xStorage );
1480 					xComponent.dispose();
1481 
1482 					m_xStorage = xTargetStorage;
1483 					m_bOwnFile = true;
1484 
1485 					XTransactedObject xTransact = (XTransactedObject)UnoRuntime.queryInterface( XTransactedObject.class,
1486 																							m_xStorage );
1487 					if ( xTransact != null )
1488 						xTransact.commit();
1489 				}
1490 				else
1491 					JOptionPane.showMessageDialog( m_aFrame, "No XEmbedPersist!", "Error:", JOptionPane.ERROR_MESSAGE );
1492 			}
1493 			else
1494 				JOptionPane.showMessageDialog( m_aFrame,
1495 												"Can't create StorageFactory!",
1496 												"Error:",
1497 												JOptionPane.ERROR_MESSAGE );
1498 		}
1499 		catch( Exception e )
1500 		{
1501 			JOptionPane.showMessageDialog( m_aFrame, e, "Exception in saveStorageToFileURI():", JOptionPane.ERROR_MESSAGE );
1502 		}
1503 
1504 	}
1505 
1506 	public void loadFileURI( String aFileURI )
1507 	{
1508 		try
1509 		{
1510 			Object oStorageFactory = m_xServiceFactory.createInstance( "com.sun.star.embed.StorageFactory" );
1511 			XSingleServiceFactory xStorageFactory = (XSingleServiceFactory)UnoRuntime.queryInterface(
1512 																						XSingleServiceFactory.class,
1513 																						oStorageFactory );
1514 			Object aArgs[] = new Object[2];
1515 			aArgs[0] = aFileURI;
1516 			aArgs[1] = new Integer( ElementModes.ELEMENT_READWRITE );
1517 
1518 			Object oStorage = xStorageFactory.createInstanceWithArguments( aArgs );
1519 			XStorage xTargetStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oStorage );
1520 
1521 			Object oEmbedCreator = m_xServiceFactory.createInstance( "com.sun.star.embed.EmbeddedObjectCreator" );
1522 			XEmbedObjectCreator xEmbedCreator = (XEmbedObjectCreator)UnoRuntime.queryInterface(
1523 																					XEmbedObjectCreator.class,
1524 																					oEmbedCreator );
1525 
1526 			XNameAccess xNameAccess = (XNameAccess)UnoRuntime.queryInterface( XNameAccess.class,
1527 																			xTargetStorage );
1528 			if ( xNameAccess == null )
1529 			{
1530 				JOptionPane.showMessageDialog( m_aFrame, "No XNameAccess!", "Error:", JOptionPane.ERROR_MESSAGE );
1531 				return;
1532 			}
1533 
1534 			Object oEmbObj = null;
1535 			if ( xNameAccess.hasByName( "LinkName" ) && xTargetStorage.isStreamElement( "LinkName" ) )
1536 			{
1537 			/*
1538 				// OOo links will not be tested until they have correct persistence
1539 				XStream xLinkStream = xTargetStorage.openStreamElement( "LinkName", ElementModes.ELEMENT_READ );
1540 				if ( xLinkStream != null )
1541 				{
1542 					XInputStream xInStream = xLinkStream.getInputStream();
1543 					if ( xInStream != null )
1544 					{
1545 						byte[][] pBuff = new byte[1][0];
1546 						int nRead = xInStream.readBytes( pBuff, 1000 );
1547 						m_aLinkURI = new String( pBuff[0] );
1548 						xInStream.closeInput();
1549 						oEmbObj = xEmbedCreator.createInstanceLink( m_aLinkURI );
1550 						m_bLinkObj = true;
1551 					}
1552 				}
1553 			*/
1554 			}
1555 			else
1556 				oEmbObj = xEmbedCreator.createInstanceInitFromEntry( xTargetStorage,
1557 																	"EmbedSub",
1558 																	false,
1559 																	new PropertyValue[0] );
1560 
1561 			m_xEmbedObj = (XEmbeddedObject)UnoRuntime.queryInterface( XEmbeddedObject.class, oEmbObj );
1562 
1563 			if ( m_xEmbedObj != null )
1564 			{
1565 				m_xStorage = xTargetStorage;
1566 				m_bOwnFile = true;
1567 			}
1568 			else
1569 				JOptionPane.showMessageDialog( m_aFrame,
1570 											   "Can't create EmbedObject from storage!",
1571 											   "Error:",
1572 											   JOptionPane.ERROR_MESSAGE );
1573 		}
1574 		catch( Exception e )
1575 		{
1576 			JOptionPane.showMessageDialog( m_aFrame, e, "Exception in loadFileURI():", JOptionPane.ERROR_MESSAGE );
1577 		}
1578 	}
1579 
1580 	public void storeLinkToStorage()
1581 	{
1582 		if ( m_xStorage != null && m_bLinkObj )
1583 		{
1584 			try {
1585 				XStream xLinkStream = m_xStorage.openStreamElement( "LinkName", ElementModes.ELEMENT_WRITE );
1586 
1587 				if ( xLinkStream != null )
1588 				{
1589 					XOutputStream xLinkOutStream = xLinkStream.getOutputStream();
1590 					XTruncate xTruncate = (XTruncate) UnoRuntime.queryInterface( XTruncate.class,
1591 																			 	xLinkOutStream );
1592 					if ( xLinkOutStream != null && xTruncate != null )
1593 					{
1594 						xTruncate.truncate();
1595 
1596 						char[] aLinkChar = m_aLinkURI.toCharArray();
1597 						byte[] aLinkBytes = new byte[ aLinkChar.length ];
1598 						for ( int ind = 0; ind < aLinkChar.length; ind++ )
1599 							aLinkBytes[ind] = (byte)aLinkChar[ind];
1600 
1601 						xLinkOutStream.writeBytes( aLinkBytes );
1602 						xLinkOutStream.closeOutput();
1603 
1604 						XComponent xComponent = (XComponent) UnoRuntime.queryInterface( XComponent.class,
1605 																						xLinkStream );
1606 						if ( xComponent != null )
1607 							xComponent.dispose();
1608 					}
1609 					else
1610 						JOptionPane.showMessageDialog( m_aFrame,
1611 														"The substream can not be truncated or written!",
1612 														"Error:",
1613 														JOptionPane.ERROR_MESSAGE );
1614 
1615 				}
1616 				else
1617 					JOptionPane.showMessageDialog( m_aFrame,
1618 													"Can't create/open substream!",
1619 													"Error:",
1620 													JOptionPane.ERROR_MESSAGE );
1621 			}
1622 			catch( Exception e )
1623 			{
1624 				JOptionPane.showMessageDialog( m_aFrame,
1625 											e,
1626 											"Exception in storeLinkToStorage:",
1627 											JOptionPane.ERROR_MESSAGE );
1628 
1629 			}
1630 		}
1631 	}
1632 
1633 	public void storeLinkAsFileURI( String aFileURI )
1634 	{
1635 		try {
1636 			Object oStorageFactory = m_xServiceFactory.createInstance( "com.sun.star.embed.StorageFactory" );
1637 			XSingleServiceFactory xStorageFactory = (XSingleServiceFactory)UnoRuntime.queryInterface(
1638 																						XSingleServiceFactory.class,
1639 																						oStorageFactory );
1640 			if ( xStorageFactory != null )
1641 			{
1642 				Object aArgs[] = new Object[2];
1643 				aArgs[0] = aFileURI;
1644 				aArgs[1] = new Integer( ElementModes.ELEMENT_READWRITE );
1645 
1646 				Object oStorage = xStorageFactory.createInstanceWithArguments( aArgs );
1647 				XStorage xTargetStorage = (XStorage)UnoRuntime.queryInterface( XStorage.class, oStorage );
1648 
1649 				XComponent xComponent = (XComponent)UnoRuntime.queryInterface( XComponent.class, m_xStorage );
1650 				xComponent.dispose();
1651 
1652 				m_xStorage = xTargetStorage;
1653 				m_bOwnFile = true;
1654 
1655 				storeLinkToStorage();
1656 
1657 				XTransactedObject xTransact = (XTransactedObject)UnoRuntime.queryInterface( XTransactedObject.class,
1658 																							m_xStorage );
1659 				if ( xTransact != null )
1660 					xTransact.commit();
1661 			}
1662 			else
1663 				JOptionPane.showMessageDialog( m_aFrame,
1664 												"Can't create StorageFactory!",
1665 												"Error:",
1666 												JOptionPane.ERROR_MESSAGE );
1667 		}
1668 		catch( Exception e )
1669 		{
1670 			JOptionPane.showMessageDialog( m_aFrame, e, "Exception in saveStorageToFileURI():", JOptionPane.ERROR_MESSAGE );
1671 		}
1672 	}
1673 
1674 	public String getValidURL( String sFileURL )
1675 	{
1676 		// m_xTransformer must be set!
1677 		URL[] aURLs = { new URL() };
1678 		aURLs[0].Complete = sFileURL;
1679 
1680 		try {
1681 			if ( !m_xTransformer.parseSmart( aURLs, "" ) )
1682 				throw new Exception();
1683 		}
1684 		catch( Exception e )
1685 		{
1686 			JOptionPane.showMessageDialog( m_aFrame, e, "Exception in getValidURL():", JOptionPane.ERROR_MESSAGE );
1687 		}
1688 
1689 		return aURLs[0].Complete;
1690 	}
1691 
1692 	public void disposeObject()
1693 	{
1694 		// TODO:
1695 		// usage of object, storage and bitmap painter should be locked
1696 		// but since possibility of rasecondition is very low
1697 		// it is not really required for testing application
1698 
1699 		clearObjectAndStorage();
1700 
1701 		if ( m_aBitmapPainter != null )
1702 		{
1703 			m_aBitmapPainter.disconnectListener();
1704 			m_aBitmapPainter = null;
1705 		}
1706 	}
1707 }
1708 
1709