Showing posts with label Open Office. Show all posts
Showing posts with label Open Office. Show all posts

09/04/2008

C#: Creating Tables in Open Office using C#.... Open Office Sucks and So Does Your Face

OK ... you're going to have to use your imagination a bit here because there is too much code to put everything in here ... the basic premise is as such:

// get the row counts out of my parameter => MyUserDefinedCustomTableObject is obviously a class in my app - and no, it is not a DataTable it is a Generic Matrix.
int RowCount = MyUserDefinedCustomTableObject.Rows.Count;

// get the col counts out of ma parameter
int ColCount = MyUserDefinedCustomTableObject.Rows[0].Cells.Count;

// create a context consisting of the oo bootstrap
unoidl.com.sun.star.uno.XComponentContext localContext = uno.util.Bootstrap.bootstrap();

// create a service factory to get shit from
unoidl.com.sun.star.lang.XMultiServiceFactory multiServiceFactory = (unoidl.com.sun.star.lang.XMultiServiceFactory )localContext.getServiceManager();

// create a component loader to get stuff from
XComponentLoader componentLoader = (XComponentLoader)multiServiceFactory.createInstance( "com.sun.star.frame.Desktop");

// create a frame which is basically the document reference
XFrame frame = ((unoidl.com.sun.star.text.XTextDocument)xComponent).getCurrentController().getFrame();

// the tricky part, create a dispatch helper - this is the work horse
XDispatchHelper xDispatchHelper = (XDispatchHelper )multiServiceFactory.createInstance( "com.sun.star.frame.DispatchHelper");

// this is only used if you want to set bookmark text within the table cells ... we use bookmarks as placeholders where there will be text in the future.
XNameAccess xna = ((XBookmarksSupplier)xComponent).getBookmarks();

// Create the property values - this uses a local function that I'm not nice enough to give you but on a primitive level it is propertyvalue.Name = first param, propertyvalue.value = 2nd param.
PropertyValue[] tableArgs = new unoidl.com.sun.star.beans.PropertyValue[4];
tableArgs[0] = CreateNewProperty("TableName", new uno.Any(MyUserDefinedCustomTableObject.TableName));
tableArgs[1] = CreateNewProperty("Columns", new uno.Any(ColCount));
tableArgs[2] = CreateNewProperty("Rows", new uno.Any(RowCount));

// check to determine if we should show borders
if (MyUserDefinedCustomTableObject.ShowBorders)
tableArgs[3] = CreateNewProperty("Flags", new uno.Any(9));
else
tableArgs[3] = CreateNewProperty("Flags", new uno.Any(8));

// dispatch the table creation event to the UI ...
xDispatchHelper.executeDispatch((XDispatchProvider)frame, ".uno:InsertTable", "", 0, tableArgs);

// you have a table in your document, the cursor is usually in the first cell of the table so you can use this function to jump between cells and insert text / bookmarks.
xDispatchHelper.executeDispatch((XDispatchProvider)frame, ".uno:JumpToNextCell", "", 0, new unoidl.com.sun.star.beans.PropertyValue[0]);

// if you are in a table cell and want to set the text of that cell then you can use this
cellTextArgs[0] = CreateNewProperty("Text", new uno.Any("My lovely text i love you text"));
xDispatchHelper.executeDispatch((XDispatchProvider)frame, ".uno:InsertText", "", 0, cellTextArgs);

// if you want to insert a bookmark into the cell you could try this (note you do not have to be in a table cell for this to insert a bookmark).
PropertyValue[] cellBkmkArgs = new unoidl.com.sun.star.beans.PropertyValue[1];
cellBkmkArgs[0] = CreateNewProperty("Bookmark", new uno.Any(cell.CellBookmark));
xDispatchHelper.executeDispatch((XDispatchProvider)frame, ".uno:InsertBookmark", "", 0, cellBkmkArgs);

Over and Out

06/03/2008

Open Office Sucks and So Does Your Face (UnoRuntime + C#)

If you are stubborn, or an idiot, or you just like using junky apps Open Office is for you. This is probably one of the only situations I'd suggest paying for and installing Office 2007 / 2003. It's just worth it.

I've been doing some automation in C# / Open Office [which I would love to rename Open Orface] and have been having issues porting Java code into C# - especially with this god darn UnoRuntime B.S.

So, what the fark is UnoRuntime and how the hell do I use it in Open Office. Well, I'm not going to get into the nitty gritty about it here - rather I'm going to explain how you don't use this somewhat core seeming object when building automation in C#.

As I'm sure you are aware - UnoRuntime is not available from C# - BUT - Most of the Java examples use this object heavily to query the UI layer and for object creation (or brokering I'm no expert under the Open Orface hood).

At first I took a look into Marshal.QueryInterface method just to see if I couldn't find the UnoRuntime somewhere in the COM layer - I turned around and decided to use an elaborate try catch + reflection algorithm to gain some concrete understanding of what was in the uno objects.

As you work more with Open Office you will realize the C# library uno, and unoidl namespaces merely contain gigantic unorganized transparent object proxy's that point into completely nonintuitive open office objects. Moreover, these open office objects are heavily based on the use of Interfaces - well I looked a bit deeper into the types I was calling and low and behold - they are pretty much huge junky objects that expose a countless number of interfaces - so we don't really even need the UnoRuntime (which makes me wonder why Java uses it).

The bottom line in this article is that UnoRuntime doesn't exist in C#. If you are porting Open Orface Java code into C# then forget about UnoRuntime. Do everything through casting and shut the hell up.

Here is an example of the Java to C# difference in creating a text property replacer:

xRepDesc is of interface type: XReplaceDescriptor AND XPropertyReplace so you can just cast the xRepDesc into XPropertyReplace and boom you're running.

Java:
XPropertyReplace xPropRepl = (XPropertyReplace) UnoRuntime.queryInterface(XPropertyReplace.class, xRepDesc);

C#:
XPropertyReplace xPropRepl = ((XPropertyReplace)xRepDesc);

Just in case you don't know, you create the xRepDesc object by, guess what - casting xComponent (of type - you guessed it XComponet - seriously wtf is an XComponent):

XReplaceDescriptor xRepDesc = ((unoidl.com.sun.star.util.XReplaceable)xComponent).createReplaceDescriptor();

I'm going to go ahead and call this automarshalling and be done with it. It sucks and if I had a server app I'd be tempted to write all my Open Orface automation in Java and write a high level COM abstraction to port a simple oAssWrapper.RunJunk(params) method and not have to deal with the hassle - OR - just go the Open Document route and use MS Word automation and then merely use open office to convert the document.

Over And Out