[api-dev] Do all calls into Office require the XCallback
Hi Mikhail, I make many calls to Office and I am wondering if they all need to be called from the Xcallback.notify() method. N - No Y - Yes O - Optional for logging ? - Don't know These are my best quesses Method Needs Needs Listener Callback Listener XComponentLoader from Desktop .loadComponentFromUrlY N doc.XEventListener ?? OnLoadFinished ?? OnLoadDone XDesktop.terminate Y O XTerminateListener XComponentLoader from Frame .loadComponentFromUrlY N doc.XEventListener ?? OnLoadFinished ?? OnLoadClosed XDocumentInsertable .insertDocumentFromURL Y N doc.XEventListener ?? OnInsertDone ?? OnLoadDone ?? OnLoadFinished XDocumentIndex.updateY ? ??? XRefreshable.refresh Y Y XRefreshListener XPrintable.print (with Wait) Y N XPrintListener XStorable.storeToURL Y Y doc.XEventListener ?? OnSaveDone ?? OnSaveAsDone ?? OnSaveFinished XCloseable.close ? O lang.XEventListener XComponent.dispose ? O lang.XEventListener UnoRuntime.queryInterfaceN N XComponent.addEventListener N N XComponentContext.getServiceManager N N XMultiComponentFactory .createInstanceWithContext N N XDesktop.addTerminateListenerN N XModel.getCurrentController N N XController.getFrame N N XTextDocument.getTextN N XText.createTextCursor N N XModifiable.setModified N N XDocumentIndexesSupplier .getDocumentIndexes N N XServiceInfo.supportsService N N XRefreshable.addRefreshListener N N XRefreshable.removeRefreshListener N N XPrintable.setPrinterN N XPrintJobBroadcaster .addPrintJobListener N N XPrintJobBroadcaster .removePrintJobListener N N Is this correct? Thank you very much, Daniel -Original Message- From: mikhail.voite...@sun.com [mailto:mikhail.voite...@sun.com] Sent: February 25, 2009 2:56 AM To: dev@api.openoffice.org Subject: Re: [api-dev] Xstorable.storeToUrl locks soffice.bin Hi Daniel, Sorry, but this is not exactly what I mean. First of all the main idea of the callback is to call the office API method from it. Thus the OOoWaitCallback should call XComponentLoader.loadComponentFromURL() and etc from notify() call. To reach this, the information about kind of call and about arguments should be provided in constructor in this case. Just to explain the mechanics for better understanding. When java application calls an UNO API method through a bridge, a new thread is created on Office side and the method is executed in this thread. When the XRequestCallback.addCallback() is called it sends a notification with arguments to the main office thread and returns. After a while the main thread calls XCallback::notify(), and if this method does a call to the office back, the call is handled in the office main thread. Second, I assume that it is not necessary in your implementation to check the thread name. In the example I have mentioned the thread name was used to mark the thread that was called from office thread, and thus needed no workaround. In your case it is not possible I assume, so I would just remove the check and use the callback workaround always. As for the listeners, I do not know details of XDocumentIndex.update() implementation. But at least XComponentLoader.loadComponentFromURL() and XStorable.storeToURL() should be synchronous, and thus do not really need any kind of listener usually. Although there is a problem in case of XComponent.loadComponentFromURL(). In case a html filter is used to load a document, the filter does some actions asynchronously. This is already recognized as a wrong behavior, but I am not sure whether it was completely fixed. Hope that helps. Best regards, Mikhail. On 02/24/09 21:55, Daniel Brosseau wrote: Hi again Mikhail, This is what I did using the AsyncCallback: I created a class on the model of the MainThreadDialogExecutor.java you pointed me to: public class OooWaitCallback implements XCallback { private boolean m_bCalled = false
RE: [api-dev] Do all calls into Office require the XCallback
Hi Mikhail, I put all my calls in an XCallback except for the startup connect upto getting the XDesktop and the final aurevoir XDesktop.terminate. It works, after some fussing about, and is about 30% quicker than the implementation I had before (uses more CPU cycles though). A few side issues: 1 - the api documentation says thet the aData argument of the notify method is An Any but the java implementation of Xcallable.notify requires an Object. The addCallback method also takes an Object as second argument. However, I tried using an Object and this threw an exception so an Any is really what is required. The implementation of XCallable should probably reflect the documentation and be notify( Any aData ) rather than notify( Object aData )? 2 - the problem with a XComponentLoader.loadFromUrl not closing the previous model also seems to affect Xdesktop.terminate because if I just terminate without Closing the old Model there is a .~lock file that stays around whereas if I Close the xModel after the terminate the .~lock file is no longer there. 3 - I have noticed that when I do not Close the old model after a new loadFromUrl, the memory usage of soffice rises rather rapidly and even after my connection closes the memory usage does not go down. So, every time I run the application, the memory usage of soffice increases. For example, the first time I run the application, soffice will use 70 MB. After 5 runs of the application soffice uses 500 MB. If I Close the old Model after a new loadFromUrl then the memory usage of soffice does not rise as much, but it rises nontheless, going from 70 MB to 75 MB after 5 runs. I suspect that when there is a new loadFromUrl into an old Frame, more than the old Model needs to be cleaned up. I noticed for example that the new Model's Controller is different from the old Model's Controller (UnoRuntime.areSame) so the old Controller might not be deleted. But even when I Close the old Controller, memory still rises, again more slowly. So something else is hanging around. Thank you very much for your help, Daniel -Original Message- From: Daniel Brosseau [mailto:dan...@lba.ca] Sent: February 25, 2009 11:19 AM To: dev@api.openoffice.org Subject: [api-dev] Do all calls into Office require the XCallback Hi Mikhail, I make many calls to Office and I am wondering if they all need to be called from the Xcallback.notify() method. N - No Y - Yes O - Optional for logging ? - Don't know These are my best quesses Method Needs Needs Listener Callback Listener XComponentLoader from Desktop .loadComponentFromUrlY N doc.XEventListener ?? OnLoadFinished ?? OnLoadDone XDesktop.terminate Y O XTerminateListener XComponentLoader from Frame .loadComponentFromUrlY N doc.XEventListener ?? OnLoadFinished ?? OnLoadClosed XDocumentInsertable .insertDocumentFromURL Y N doc.XEventListener ?? OnInsertDone ?? OnLoadDone ?? OnLoadFinished XDocumentIndex.updateY ? ??? XRefreshable.refresh Y Y XRefreshListener XPrintable.print (with Wait) Y N XPrintListener XStorable.storeToURL Y Y doc.XEventListener ?? OnSaveDone ?? OnSaveAsDone ?? OnSaveFinished XCloseable.close ? O lang.XEventListener XComponent.dispose ? O lang.XEventListener UnoRuntime.queryInterfaceN N XComponent.addEventListener N N XComponentContext.getServiceManager N N XMultiComponentFactory .createInstanceWithContext N N XDesktop.addTerminateListenerN N XModel.getCurrentController N N XController.getFrame N N XTextDocument.getTextN N XText.createTextCursor N N XModifiable.setModified N N XDocumentIndexesSupplier .getDocumentIndexes N N XServiceInfo.supportsService N N XRefreshable.addRefreshListener N N XRefreshable.removeRefreshListener N N XPrintable.setPrinterN N XPrintJobBroadcaster .addPrintJobListener N N XPrintJobBroadcaster .removePrintJobListener N N Is this correct? Thank you very much, Daniel
RE: [api-dev] Xstorable.storeToUrl locks soffice.bin
java.io.BufferedReader.readLine:362 ooo.connector.server.OOServer$1.run:143 'Tread-1' suspended at 'sun.print.Win32PrintServiceLookup.notifyPrinterChange' Hidden Source Calls sun.print.Win32PrintServiceLookup.notifyPrinterChange sun.print.Win32PrintServiceLookup.access$100:32 sun.print.Win32PrinterServiceLookup$PrinterChangeListener.run:302 I hope this helps in finding where the problem lies. Could you please signal me if there is something I am doing wrong? Regards, Daniel -Original Message- From: mikhail.voite...@sun.com [mailto:mikhail.voite...@sun.com] Sent: February 24, 2009 4:19 AM To: dev@api.openoffice.org Subject: Re: [api-dev] Xstorable.storeToUrl locks soffice.bin Hi Daniel, First of all what do you name the main thread? As I understood you use own java application that connects the office using UNO API. The main thread of the java application does not correspond to the main thread of the office process it connects ( at least it was so before ). As I have written in one of my previous answers, please try to use com.sun.star.awt.AsyncCallback service to get a callback from the office main thread. In this case you can use the callback to do your API call in the office main thread. The remaining lock file looks in this case like a result of non-closed model. The model is the object that creates lock file on document opening and closes it on closing. The office never waits for a document lock file to continue, except the case of error/query message shown during document opening/storing. Anyway, the stack of the deadlock would be very interesting. Best regards, Mikhail. On 02/24/09 07:05, Daniel Brosseau wrote: Hi, In everything done in one main thread with no GUI, my program loadsFromUrl from the Frame a first ODT file and then appends one or more ODT files to this through a XTextCursor and XDocumentInsertable. After all files are appended I do a XRefreshable.refresh(). I then move to the beginning of the XTextDocument and insert a Table of Contents, do another XRefreshable.refresh() and a XDocumentIndex.update which I retreived through a XServiceInfo. At this point I can do one of two things: i) print the document through a XPrintable with a property Wait of true and for belts and suspenders a XPrintJobListener and XPrintJobBroadcaster (I do not think I need this with Wait) Or ii) storeToUrl through a XStorable using the PDF filter writer_pdf_Export, Asynchron of false and Overwrite true. The program then loops back to the beginning and loadsFromUrl/Append/etc for another set of files ... (after the load I close the released Xmodel, but am I leaking a Controller which I should also close?) If all I do is print, the the program can handle several sets of files without a problem but if I storeToUrl then soffice.bin will typically hang after 1 to 5 stores. The specific set of loaded files that causes soffice.bin to hang varies from run to run but inevitably soffice.bin hangs. In the directory from which the files are loaded, I see Appear a file .~lock.fileName.ODT# where the fileName is the name of first file of the set that was loaded through loadFromUrl which corresponds to the XModel's URL property. Evidently, having soffice.bin hang is a problem. What I don't know is if i) it is a threading issue relating to synchronization of the store, the refresh or the update Or ii) their is a file lock taken out that soffice.bin is waiting to have released before continuing. Really what I would like to know is how to avoid the hanging soffice.bin. When soffice.bin hangs, it just sits there consumming around 20% of the CPU with no change to memory usage, bytes read or anything else. Any hints? Thank you, Daniel Brosseau - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org
RE: [api-dev] Xstorable.storeToUrl locks soffice.bin
Hi again Mikhail, This is what I did using the AsyncCallback: I created a class on the model of the MainThreadDialogExecutor.java you pointed me to: public class OooWaitCallback implements XCallback { private boolean m_bCalled = false; static public boolean WaitOnOoo( XComponentContext xContext ) { OooWaitCallback aExecutor = new OooWaitCallback(); return GetCallback( xContext, aExecutor ); } static private boolean GetCallback ( XComponentContext xContext, OooWaitCallback aExecutor ) { try { if ( aExecutor != null ) { String aThreadName = null; Thread aCurThread = Thread.currentThread(); if ( aCurThread != null ) aThreadName = aCurThread.getName(); if ( aThreadName != null aThreadName.equals( main ) ) { // the main thread should be accessed asynchronously XMultiComponentFactory xFactory = xContext.getServiceManager(); if ( xFactory == null ) throw new com.sun.star.uno.RuntimeException(); XRequestCallback xRequest = (XRequestCallback)UnoRuntime.queryInterface( XRequestCallback.class, xFactory.createInstanceWithContext ( com.sun.star.awt.AsyncCallback, xContext ) ); if ( xRequest != null ) { xRequest.addCallback( aExecutor, Any.VOID ); do { Thread.yield(); } while( !aExecutor.m_bCalled ); } } else { // handle it as a main thread aExecutor.notify( Any.VOID ); } } } catch( Exception e ) { e.printStackTrace(); } return true; } public void notify( Object aData ) { m_bCalled = true; } }; Immediately after each call to openOffice.org in my main program such as xCloseable.close() or xComponentLoader.loadFromUrl() or xDocumentIndex.update() etc I make a call to OooWaitCallback.WaitOnOoo(). I have now tested the program several times and where before without the WaitOnOoo calls it would consistently hang, it has not hung once. What I understand is happening is the callback request is being placed in the job queue that soffice.bin has been requested to handle. This callback request will be honored once soffice.bin has finished its previous business as everything is happening synchronously. Until soffice calls the callback, my main thread is yielding. Does it make sens that as I have implemented it, this would resolve the problem? Also, Because everything is happening synchronously, I really should not need any listeners? Regards, Daniel -Original Message- From: mikhail.voite...@sun.com [mailto:mikhail.voite...@sun.com] Sent: February 24, 2009 4:19 AM To: dev@api.openoffice.org Subject: Re: [api-dev] Xstorable.storeToUrl locks soffice.bin Hi Daniel, First of all what do you name the main thread? As I understood you use own java application that connects the office using UNO API. The main thread of the java application does not correspond to the main thread of the office process it connects ( at least it was so before ). As I have written in one of my previous answers, please try to use com.sun.star.awt.AsyncCallback service to get a callback from the office main thread. In this case you can use the callback to do your API call in the office main thread. The remaining lock file looks in this case like a result of non-closed model. The model is the object that creates lock file on document opening and closes it on closing. The office never waits for a document lock file to continue, except the case of error/query message shown during document opening/storing. Anyway, the stack of the deadlock would be very interesting. Best regards, Mikhail. On 02/24/09 07:05, Daniel Brosseau wrote: Hi, In everything done in one main thread with no GUI, my program loadsFromUrl from the Frame a first ODT file and then appends one or more ODT files to this through a XTextCursor and XDocumentInsertable. After all files are appended I do a XRefreshable.refresh(). I then move to the beginning of the XTextDocument and insert a Table of Contents, do another XRefreshable.refresh() and a XDocumentIndex.update which I retreived through a XServiceInfo. At this point I can do one of two things: i) print the document through a XPrintable with a property Wait of true and for belts and suspenders a XPrintJobListener and XPrintJobBroadcaster (I do not think I need this with Wait) Or ii) storeToUrl through a XStorable using the PDF filter writer_pdf_Export, Asynchron of false and Overwrite true. The program then loops back to the beginning and loadsFromUrl/Append/etc for another set of files ... (after the load I close the released Xmodel, but am I leaking a Controller which I should also close?) If all I
[api-dev] Synchronous XDocumentIndex update, XRefereshable refresh, XStorable storeToUrl
Hi, I insert a Table of Contents into an Xmodel, ContentIndex service represented by XDocumentIndex interface. Then I call XDocumentIndex.update(). Is the update absolutely synchronous? Is there a listener I can use to make sure the update is finished? I also call XRefreshable.refresh(). Is refresh synchronous or do I have to use a XRefeshListener? I later call XStorable.storeToUrl. Is storeToUrl also synchronous? Is there a store listener I can use? Thank you very much, Daniel - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org
RE: [api-dev] How to attach new Model to old Controller
Hi Mikhail, Thank you for your explanations. With regards to the Controller not closing the Model on loadTromUrl, I would rather the bug stay in because the workaround is very easy and I do not know how you would keep a Model alive and detach it from its Controller if you could not do it this way. It is a step towards orthogonality. Unless the Frame creates both a Controller and a Model on loadFromUrl and just Closing the Model after the load keeps a Controller in limbo somewhere, there is no harm done by having to dispose the replaced Model afterwards, but it opens the door to greater flexibility. Regards, Daniel -Original Message- From: mikhail.voite...@sun.com [mailto:mikhail.voite...@sun.com] Sent: February 20, 2009 4:58 AM To: dev@api.openoffice.org Subject: Re: [api-dev] How to attach new Model to old Controller Hi Daniel, On 02/20/09 02:49, Daniel Brosseau wrote: Hi Mikhail, Frank, Thank you again. since it would allow returning more information (and thus would have saved you the question, since you would have got a message saying not allowed for this implementation). As an extreemly minor point: I got a return of false and not not allowed for this implementation :) I have tried loading at the Frame level. I get the Frame by first loading a _blank component from the Desktop's XComponentLoader and then moving up from the XComponent's XModel to the XController to the XFrame. I then get the XFrame's XComponentLoader to load subsequent URL's into the Frame. The load replaces the previous Model but does not close it This is a bug. I have just written a small basic script to test this, and indeed in case a document is loaded as hidden one, the controller does not close the model. In case of visible documents it works well, the model is closed. Could you please write a bug to me. so I close the previous Model after the Frame is loaded with the new URL. If I do not close the previous Model, the memory usage in soffice.bin increases continuously with each load. Yes, a model has to be closed to end the objects lifetime. This is designed so, because the complex system of objects let cycle dependencies appear. And since the controller erroneously does not try to close it in this case, it stays open. In these circumstances your workaround to close the model after it is replaced in the frame is absolutely correct. After the mentioned above bug is fixed it will not be necessary any more. You can implement the workaround so that it is ready for DisposedException. If controller closes the model after the fix, the next try to close it will throw the exception ). This scheme is definitely much more stable than anything I tries before. Thanks :) Glad that it helps :) If I close the old XModel before the load of the new URL I destroy the whole Model-Controller-Frame structure. It is designed so. When a model of a frame is explicitly closed, it means that the document is closed. Since the model is still attached to the structure, the whole structure is closed. From other side if the frame is closed it disposes the controller. And the controller should close the related model if it is the last view of the document. I have tried to use XDesktop.terminate() at the end but this hangs or crashes so I just dispose the Xdesktop through it's XComponent interface. That is not correct. To shutdown office per API the terminate() call should be used. Please see the following link for details. http://wiki.services.openoffice.org/wiki/Documentation/DevGuid e/OfficeDev/Using_the_Desktop The fact that the call let office crash/hang is a problem. The developers guide mentiones that modified documents might be a problem in this case. Please try to set all remaining documents to nonmodified state before terminating and probably close them. Please also check that the call is done in the main thread. If not, please try the workaround to let it be triggered from the main thread that I have posted yesterday. Anyway, could you please send the crash when it crashes next time. You could use crashreporter for this, in this case it would be enough just to provide the crash ID to allow to find the stack. When I load a new URL I use the property ( Asynchron,false ). I am not certain this is required but I quess (you see I guess too) this uses the SynchronousFrameLoader service. Normally the loadComponentFromURL() should be always synchron. So this call should let the default scenario be used. Thank you both again, Daniel PS On the question of design, I guess my questions arose because as a recent re-comer to OpenOffice.org I concluded wrongly from the general tone of the API and the documentation that the Frame-Controller-Model paradigm was orthogonal and that each represented
[api-dev] Xstorable.storeToUrl locks soffice.bin
Hi, In everything done in one main thread with no GUI, my program loadsFromUrl from the Frame a first ODT file and then appends one or more ODT files to this through a XTextCursor and XDocumentInsertable. After all files are appended I do a XRefreshable.refresh(). I then move to the beginning of the XTextDocument and insert a Table of Contents, do another XRefreshable.refresh() and a XDocumentIndex.update which I retreived through a XServiceInfo. At this point I can do one of two things: i) print the document through a XPrintable with a property Wait of true and for belts and suspenders a XPrintJobListener and XPrintJobBroadcaster (I do not think I need this with Wait) Or ii) storeToUrl through a XStorable using the PDF filter writer_pdf_Export, Asynchron of false and Overwrite true. The program then loops back to the beginning and loadsFromUrl/Append/etc for another set of files ... (after the load I close the released Xmodel, but am I leaking a Controller which I should also close?) If all I do is print, the the program can handle several sets of files without a problem but if I storeToUrl then soffice.bin will typically hang after 1 to 5 stores. The specific set of loaded files that causes soffice.bin to hang varies from run to run but inevitably soffice.bin hangs. In the directory from which the files are loaded, I see Appear a file .~lock.fileName.ODT# where the fileName is the name of first file of the set that was loaded through loadFromUrl which corresponds to the XModel's URL property. Evidently, having soffice.bin hang is a problem. What I don't know is if i) it is a threading issue relating to synchronization of the store, the refresh or the update Or ii) their is a file lock taken out that soffice.bin is waiting to have released before continuing. Really what I would like to know is how to avoid the hanging soffice.bin. When soffice.bin hangs, it just sits there consumming around 20% of the CPU with no change to memory usage, bytes read or anything else. Any hints? Thank you, Daniel Brosseau - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org
RE: [api-dev] How to attach new Model to old Controller
Hello Frank, With regards to getting the frame from the desktop I used the xDesktop.getCurrentFrame() API. This returned null. With regards to Q2, I do initNew() the model: class oooTests { static void controller( XMultiComponentFactory xServiceManager, XComponentContext xComponentContext, LbaLogger lbaLogger ) throws java.lang.Exception { XModel xModel_A = null; XModel xModel_B = null; XInterface xInterface = (XInterface) xServiceManager.createInstanceWithContext( com.sun.star.frame.Desktop, xComponentContext ); XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface( XDesktop.class, xInterface ); // XFrame xFrame = xDesktop.getCurrentFrame(); // This returns null PropertyValue[] openProperties = new PropertyValue[1]; openProperties[0] = new PropertyValue(); openProperties[0].Name = Hidden; openProperties[0].Value = new Boolean(true); XComponentLoader xComponentLoader = (XComponentLoader) UnoRuntime.queryInterface( XComponentLoader.class, xDesktop ); XComponent xComponent = xComponentLoader.loadComponentFromURL( private:factory/swriter, _blank, 0, openProperties ); xModel_A = (XModel) UnoRuntime.queryInterface( XModel.class, xComponent ); xInterface = (XInterface) xServiceManager.createInstanceWithContext( com.sun.star.text.TextDocument, xComponentContext ); xModel_B = (XModel) UnoRuntime.queryInterface( XModel.class, xInterface ); xComponent = (XComponent) UnoRuntime.queryInterface( XComponent.class, xInterface ); XLoadable xLoadable = (XLoadable) UnoRuntime.queryInterface( XLoadable.class, xInterface ); xLoadable.initNew(); XController xController = xModel_A.getCurrentController(); if ( xController.attachModel( xModel_B ) ) lbaLogger.info( Sucessfully attached xModel_B to desktop controller ); else lbaLogger.info( Did not sucessfully attach xModel_B to desktop controller ); } // oooTest This returned: Did not sucessfully attach xModel_B to desktop controller Meaning the xModel_B was not attached. Any reason why? Thank you, Daniel -Original Message- From: frank.schoenh...@sun.com [mailto:frank.schoenh...@sun.com] Sent: February 19, 2009 2:15 AM To: dev@api.openoffice.org Subject: Re: [api-dev] How to attach new Model to old Controller Hi Daniel, Q1: Why can't I retieve the XFrame starting from the top (XDesktop) while I can get it starting from the bottom (XModel)? Hard to answer without knowing how exactly you tried to retrieve the frame. I'd say that iterating over the frames at the desktop, and checking for a frame whose model is the one returned by loadComponentFromURL, should give you the frame. Is this what you do? I sucessfully create a second XModel through the service manager xServiceManager.createInstanceWithContext ( com.sun.star.text.TextDocument, xComponentContext ) Call this xModel_B Now what I would like to do is replace xModel_A with xModel_B. I tried calling the XController.attachModel( xModel_B ) which returns False meaning the new model was not attached. Q2: How to I replace xModel_A with xModel_B in the Frame-Controller-Model Structure? attachModel should be the right thing to do, however, I would not bet that all implementations properly support it. However, you did not mention that you initialized the second model after creating it. You should call one of the two XLoadable methods (initNew or load) before doing anything else with the model. Ciao Frank -- - Frank Schönheit, Software Engineer frank.schoenh...@sun.com - - Sun Microsystems http://www.sun.com/staroffice - - OpenOffice.org Base http://dba.openoffice.org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org
RE: [api-dev] How to attach new Model to old Controller
Hi Mikhail, Frank, Thank you again. since it would allow returning more information (and thus would have saved you the question, since you would have got a message saying not allowed for this implementation). As an extreemly minor point: I got a return of false and not not allowed for this implementation :) I have tried loading at the Frame level. I get the Frame by first loading a _blank component from the Desktop's XComponentLoader and then moving up from the XComponent's XModel to the XController to the XFrame. I then get the XFrame's XComponentLoader to load subsequent URL's into the Frame. The load replaces the previous Model but does not close it so I close the previous Model after the Frame is loaded with the new URL. If I do not close the previous Model, the memory usage in soffice.bin increases continuously with each load. This scheme is definitely much more stable than anything I tries before. Thanks :) If I close the old XModel before the load of the new URL I destroy the whole Model-Controller-Frame structure. I have tried to use XDesktop.terminate() at the end but this hangs or crashes so I just dispose the Xdesktop through it's XComponent interface. When I load a new URL I use the property ( Asynchron,false ). I am not certain this is required but I quess (you see I guess too) this uses the SynchronousFrameLoader service. Thank you both again, Daniel PS On the question of design, I guess my questions arose because as a recent re-comer to OpenOffice.org I concluded wrongly from the general tone of the API and the documentation that the Frame-Controller-Model paradigm was orthogonal and that each represented relatively independent blocks that could be manipulated individually. But I realize that in the implementation, the complexity of the interactions really has meant that they form a relatively monolithic block. In fact, in the API that gets commonly used we ask the Frame to give us a Model (XComponentLoader.loadFromURL()!). Nothing wrong with this. I was just going with the flow and infering things from the API and documentation that werent there. As long as I understand and it works, that's great. -Original Message- From: frank.schoenh...@sun.com [mailto:frank.schoenh...@sun.com] Sent: February 19, 2009 11:16 AM To: dev@api.openoffice.org Subject: Re: [api-dev] How to attach new Model to old Controller Hi Daniel, I guess there is a theoretical API and a real api. Well, as Mikhail said, the API definition allows for rejecting an attempt to attach a new model. As a secondary thought, I'd say that a VetoException or something like this would have been a better API design, since it would allow returning more information (and thus would have saved you the question, since you would have got a message saying not allowed for this implementation). I take it then that exchanging models can't be done? Yes. However, it would be interesting to know what you want to achieve with this. Even if replacing a model at an existing controller would be implemented, there's hardly any aspect of the controller which would survive this. In other words, the controller would implicitly need to reset itself to a state which pretty much equals its state when it's newly created, and got its very first model. That said, perhaps Mikhails suggestion to simply load the new document into the existing frame suits your needs. Is there a quick way to exchange or replace the contents of a Model with that of another model? Try using XLoadable::load a second time. If your Model_B really exists as model only (and not as file), then store it to a temporary location beforehand. In my understanding, XLoadable::load should be reusable, though I of course do not know whether its implemented this way everywhere :) Depending on your application architecture, you need to care for side effects. E.g. if some of your components caches any direct or indirect property (in a very broad sense) of the model, you need to invalidate all those data. Again, I think evaluating the load another document into the same frame approach is worth an evaluation, to prevent this kind of problems. Ciao Frank -- - Frank Schönheit, Software Engineer frank.schoenh...@sun.com - - Sun Microsystems http://www.sun.com/staroffice - - OpenOffice.org Base http://dba.openoffice.org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org
RE: [api-dev] Xprintable getPrinter returns a zero length sequence
Thank you Mikhail, The reason I am trying to do it this way is that we need to print or convert thousands of documents each month and when I create a Model Frame and Controller, OpenOffice inevitablly hangs after a short while, probably something to do with threading in OpenOffice and maybe finalizers in java. So I am trying to keep the number of objects and interactions to an absolute minimum to see if that helps. As a result, except for printing, the behaviour of OpenOffice does seems much more stable. So could you point me in the right direction as to how to create the frame or the view an attach it to the model without a Controller (if that's possible) in a way that would enable printing. Daniel -Original Message- From: Mikhail Voitenko [mailto:mikhail.voite...@sun.com] Sent: February 18, 2009 2:27 AM To: dev@api.openoffice.org Subject: Re: [api-dev] Xprintable getPrinter returns a zero length sequence Hi Daniel, Currently the model needs view to be able to print. To prevent showing of the document after loading please try to load it using loadComponentFromURL method and provide Hidden parameter in MediaDescriptor. That should create an invisible frame for the document, and the printing should be possible in this case. Best regards, Mikhail. On 02/18/09 03:17, Daniel Brosseau wrote: Hi, I am afraid I am stumped and need some help with this. I have a component, a com.sun.star.text.TextDocument that has only an Xmodel, no Frame or Controller, that I have populated throupgh a Xloadable.load. The component has loaded succesfully and I can get its properties through XPropertySet and XPropertySetInfo. It has content, word count, character count, etc 0 and I can extract text through XTextCursor.getString(). I can extract the Xmodel's URL without a problem. So far so good. The problem is when I come to print. I get the XPrintable interface XPrintable xPrintable = (XPrintable) UnoRuntime.queryInterface( XPrintable.class, xComponent ); if ( xPrintable == null ) return; XPrintJobBroadcaster xPrintJobBroadcaster = (XPrintJobBroadcaster) UnoRuntime.queryInterface( XPrintJobBroadcaster.class, xPrintable ); LocalPrintJobListener xPrintJobListener = new LocalPrintJobListener(); xPrintJobBroadcaster.addPrintJobListener( xPrintJobListener ); PropertyValue[] printerDesc = new PropertyValue[1]; printerDesc[0] = new PropertyValue(); printerDesc[0].Name = Name; printerDesc[0].Value = printerName; xPrintable.setPrinter( printerDesc ); printerDesc = xPrintable.getPrinter(); for( int i = 0; i printerDesc.length; i++ ) { m_lbaLogger.info( printerDesc[ + i + ] Name + printerDesc[i].Name + , value + printerDesc[i].Value.toString() ); } dsUrl = dsUrl.replace( '\\', '/' ); PropertyValue[] printOpts = new PropertyValue[4]; printOpts[0] = new PropertyValue(); printOpts[0].Name = FileName; printOpts[0].Value = dsUrl; printOpts[1] = new PropertyValue(); printOpts[1].Name = CopyCount; printOpts[1].Value = new Short( (short)1 ); printOpts[2] = new PropertyValue(); printOpts[2].Name = Pages; printOpts[2].Value = 1-99; printOpts[3] = new PropertyValue(); printOpts[3].Name = Wait; printOpts[3].Value = new Boolean( true ); xPrintable.print( printOpts ); int nWait = 0; int nMaxWait = 1; m_lbaLogger.info( Printing to file + dsUrl + through printer + printerName ); while ( xPrintJobListener.getState() == null || xPrintJobListener.getState() == PrintableState.JOB_STARTED ) { Thread.sleep( 100 ); nWait += 100; if ( nWait nMaxWait ) { m_lbaLogger.warning( Could not print document ); break; } } m_lbaLogger.info( Waited + nWait + ms to print document, ending print state was + xPrintJobListener.toString() ); xPrintJobBroadcaster.removePrintJobListener( xPrintJobListener ); After xPrintable.setPrinter( printerDesc ), I getPrinter() to see if anything has been set but the printerDesc array has a length of 0. Then when I try to print, the PrintJobListner always times out and the Printer's xPrintJobListener.getState() == null which means the print job did not even start. The printer name is a valid printer as confirmed by private boolean isPrinter( String printerName ) { // Look up all services javax.print.PrintService[] services = javax.print.PrintServiceLookup.lookupPrintServices( null, null ); for ( int i = 0; i
RE: [api-dev] Xprintable getPrinter returns a zero length sequence
Hi Tobias, We have tried exactly what you laid out and it does not work for us, OpenOffice hangs regularly. This is why I want to take the most out possible. What are the minimum objects I need to enable printing and how to I interface with them? Daniel -Original Message- From: Tobias Krais [mailto:tux-s...@design-to-use.de] Sent: February 18, 2009 3:25 PM To: dev@api.openoffice.org Subject: Re: [api-dev] Xprintable getPrinter returns a zero length sequence Hi Daniel, The reason I am trying to do it this way is that we need to print or convert thousands of documents each month and when I create a Model Frame and Controller, OpenOffice inevitablly hangs after a short while, probably something to do with threading in OpenOffice and maybe finalizers in java. I have the same problem. This is how I solved it: 1. I bootstrap OpenOffice.org, 2. open a document and convert it and 3. close the document. 4. Next I open the next document and convert it... The important thing is not to close OpenOffice.org. In case you always start a new Java process for each conversion, you can open a socket or something like this. Greetings, Tobias - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org
[api-dev] How to attach new Model to old Controller
Hi, I have a Frame-Controller-Model structure built through a XDesktop created through xServiceManager.createInstanceWithContext ( com.sun.star.frame.Desktop, xComponentContext ) and loadComponentFromUrl ( private:factory/swriter, _blank, 0, openProperties ) with the only openProperty being Hidden which delivers a XComponent that supports the XModel interface (call this xModel_A). I try to retrieve the XFrame from the XDesktop and it returns null. I try to retrieve the XController from the XModel with success. I try to retrieve the XFrame from the XController with success. Q1: Why can't I retieve the XFrame starting from the top (XDesktop) while I can get it starting from the bottom (XModel)? I sucessfully create a second XModel through the service manager xServiceManager.createInstanceWithContext ( com.sun.star.text.TextDocument, xComponentContext ) Call this xModel_B Now what I would like to do is replace xModel_A with xModel_B. I tried calling the XController.attachModel( xModel_B ) which returns False meaning the new model was not attached. Q2: How to I replace xModel_A with xModel_B in the Frame-Controller-Model Structure? Thank you, Daniel - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org
[api-dev] Xprintable getPrinter returns a zero length sequence
Hi, I am afraid I am stumped and need some help with this. I have a component, a com.sun.star.text.TextDocument that has only an Xmodel, no Frame or Controller, that I have populated throupgh a Xloadable.load. The component has loaded succesfully and I can get its properties through XPropertySet and XPropertySetInfo. It has content, word count, character count, etc 0 and I can extract text through XTextCursor.getString(). I can extract the Xmodel's URL without a problem. So far so good. The problem is when I come to print. I get the XPrintable interface XPrintable xPrintable = (XPrintable) UnoRuntime.queryInterface( XPrintable.class, xComponent ); if ( xPrintable == null ) return; XPrintJobBroadcaster xPrintJobBroadcaster = (XPrintJobBroadcaster) UnoRuntime.queryInterface( XPrintJobBroadcaster.class, xPrintable ); LocalPrintJobListener xPrintJobListener = new LocalPrintJobListener(); xPrintJobBroadcaster.addPrintJobListener( xPrintJobListener ); PropertyValue[] printerDesc = new PropertyValue[1]; printerDesc[0] = new PropertyValue(); printerDesc[0].Name = Name; printerDesc[0].Value = printerName; xPrintable.setPrinter( printerDesc ); printerDesc = xPrintable.getPrinter(); for( int i = 0; i printerDesc.length; i++ ) { m_lbaLogger.info( printerDesc[ + i + ] Name + printerDesc[i].Name + , value + printerDesc[i].Value.toString() ); } dsUrl = dsUrl.replace( '\\', '/' ); PropertyValue[] printOpts = new PropertyValue[4]; printOpts[0] = new PropertyValue(); printOpts[0].Name = FileName; printOpts[0].Value = dsUrl; printOpts[1] = new PropertyValue(); printOpts[1].Name = CopyCount; printOpts[1].Value = new Short( (short)1 ); printOpts[2] = new PropertyValue(); printOpts[2].Name = Pages; printOpts[2].Value = 1-99; printOpts[3] = new PropertyValue(); printOpts[3].Name = Wait; printOpts[3].Value = new Boolean( true ); xPrintable.print( printOpts ); int nWait = 0; int nMaxWait = 1; m_lbaLogger.info( Printing to file + dsUrl + through printer + printerName ); while ( xPrintJobListener.getState() == null || xPrintJobListener.getState() == PrintableState.JOB_STARTED ) { Thread.sleep( 100 ); nWait += 100; if ( nWait nMaxWait ) { m_lbaLogger.warning( Could not print document ); break; } } m_lbaLogger.info( Waited + nWait + ms to print document, ending print state was + xPrintJobListener.toString() ); xPrintJobBroadcaster.removePrintJobListener( xPrintJobListener ); After xPrintable.setPrinter( printerDesc ), I getPrinter() to see if anything has been set but the printerDesc array has a length of 0. Then when I try to print, the PrintJobListner always times out and the Printer's xPrintJobListener.getState() == null which means the print job did not even start. The printer name is a valid printer as confirmed by private boolean isPrinter( String printerName ) { // Look up all services javax.print.PrintService[] services = javax.print.PrintServiceLookup.lookupPrintServices( null, null ); for ( int i = 0; i services.length; i++ ) { if ( services[i].getName().trim().equalsIgnoreCase( printerName.trim() ) ) { return true; } } return false; } // isPrinter Is there anything evident that I am missing here? Is there any reason that an Xmodel without a Controller or Frame should not print? Any help would be greatly appreciated. Daniel - To unsubscribe, e-mail: dev-unsubscr...@api.openoffice.org For additional commands, e-mail: dev-h...@api.openoffice.org