 Okay, yeah, welcome to my talk, Diving into Extension Development. My name is Samoim Erprood, I'm working for CIB, as you can see, and the reason for this talk is I've been doing Extension Development for a client in recent times, yeah, and I want to share with you just the basics of how an extension looks like in deep office, and that should be an entry point if you want to start writing your own extension. This is about Extension Development with Java. You could also use Python or some other languages, but in this case, we'll be using Java, and we'll be using the Eclipse plugin, which helps a lot developing the extension. Yeah, this is my one and only slide, and the rest will be just a demo of how that works. Okay, so first, I'll be starting up Eclipse, and yeah, the extension is called LO Eclipse. In former days, it was OO Eclipse. It's written by Cedric Bostanat in earlier times. Was working for OpenOffice only since some recent changes in LibreOffice 5, and we adopted the extension to work also with LibreOffice and recent Eclipse releases. Yeah, seems the internet is slow, but you can find the extension on the Eclipse Marketplace. If you search for LibreOffice or LO Eclipse, so I'll skip this part now. Yeah, to get started, at the last hackfest in Las Palmas, I gave a workshop on Extension Development, and I created a started extension which contains some boilerplate you will need. You will most probably need for your extension, and I will start with this one, import the project, and then explain the structure and a little bit how to get started. This is unplanned. Let me start a new Eclipse instance. Workspaces in use, of course. Okay, so you can download this extension as a zip file. That's what I did, and unzip it, and then I will import it into Eclipse as an existing project. Select it from my desktop. Then it's called starter project. First of all, what you need to do is adjust the paths in the project properties. You need to specify which LibreOffice instance to use. Then it will detect the LibreOffice and find out the version. It takes a little bit of time. Yeah, LibreOffice 5.1. After that we do the same with the SDK. Usually the SDK, you need to install it. First of all, it's a separate download for Windows. Usually it is put in the LibreOffice SDK folder, but it can also be put somewhere else, so you need to specify it manually. Okay, so after that, there should be no red signs anymore, and you should be able to work with the extension. So this is a fully working extension. What we can do now is create a new run configuration. There is a type LibreOffice application. We select the project, our starter project. Give it a name, apply, and run. Let me close this first. And then the extension gets packaged by the Eclipse plugin. The Java gets compiled and it gets installed. There it is with some error. We try again, remove it. Now it's there, and if you go to writer, you see there has a menu been added, starter project with action one, and it opens a simple dialogue. It should open a simple dialogue. Do we have the right Java? I hope so. Yeah. Okay, we'll start with the extension structure and try to get it working later. So first of all, the basics is description.xml. That is the information you see in the extension manager. It's an XML file with a version, an identifier, and a display name, and also an extension description that is optional. And this Eclipse plugin provides a nice editor to edit these fields. Yeah, you can also define this stuff for multiple languages if you add another locale here. You can specify compatibility options, which open office, LibreOffice version, platforms like Windows, Linux, whatever, information on the extension publisher, URL to the release notes, update mirrors, and a license file. Yeah. Then there is the package.properties. It is properties file, Java properties, and there you can specify which files get included in the extension. Some files are included automatically like the description and other stuff, but if you have additional files you want to have there, you need to enable it specifically. For example, we have a dialogue file, or if you have external Java libraries, you would also need to specify them here. Okay, the types.rdb, that's a binary file, and the Eclipse plugin provides you the text representation of that. It uses some program from the SDK rec view or something like that to display the types that are in there specified by the extension. Yeah. This is a compiled version of the IDL files we have here. We have a starterproject.idl, which is a service deriving from the Xdrop executor. If you want to have menu or tool by entries in your extension, you most probably need the Xdrop executor. At least I didn't find another way how to make it work that you click on the toolbar and your extension gets activated. So then looking at the code, you have the entry point, the starterproject implementation. It implements this Xdrop executor. Yeah, this code is generated from LibreOffice code maker. It's part of the SDK as far as I know. Yeah, and yeah, there is some boilerplate code which is for the service implementation and then this is the entry point. The Xdrop executor has a trigger method and this action string, I will show you later where this comes from. There you can break down this action string and do your actions. In this case, I'm creating a dialogue, action one dialogue, I'll give it the context. It is like, I don't know how to describe it, each LibreOffice instance has one context. It's like the reference to the LibreOffice process, something like that and then I'll show the dialogue. Yeah, registration handler that is also code that you don't necessarily need, necessarily need to understand. It's being put there by the Eclipse plugin and it regresses the extension in LibreOffice and you can have multiple services and they are listed here, also added automatically by the Eclipse plugin. So this is lots of stuff you would need to do manually if you build an extension and the Eclipse plugin helps you with all these steps. Okay, so how is the dialogue implemented? We go to that class, I have it here in the dialogue package. Yeah, it implements a dialogue event handler that's an interface from UNO and then we create a dialogue. I have a helper class for that. I give it an xtl file. We'll have a look into that later. That file is located here in my dialogue folder. It's also bundled with the extension. It's an XML file similar to the UI files we have in LibreOffice, but this has been there before for extensions and it allows you to also graphically put together your dialogue. We'll have a look at that later. Yeah, okay, and then the show method just executes the dialogue so that it gets shown. Okay, I want to try again if I can get the extension working, sorry. Okay, thank you. Maybe something like this. Hope it's better. Sorry for that. Should have had a look at the presentation. Okay, I don't know. Maybe there are some other extensions. Conflicting or there has been a packaging error. This is the generated extension. It gets put in the dist folder. I'll try to install it manually. Oh no, it was the wrong one, this one also. So where is it? On the desktop property and it's gone. Okay, we'll just continue with the dialogue. So if you go to the macros, oh, this is in German now, but I hope you can understand anyway. You can have an entry managed dialogues in English and there it's a bit complicated. You need to create a new dialogue, then edit this one and then you can import a file. So this is our extension dialogue, one dialogue. So this is just an editor for dialogues. I have some labels in here and the close button. So I can add whatever widgets I think we need, maybe a text field. Now this is a label, this is a text field. Text field one, that's okay. Then we can add a button there. Yeah, this doesn't have the, you can only position the widgets manually with fixed size. It's not possible to make grids or something like that. That's not so fortunate but maybe something for a Google Summer of Code project one day. Okay, so if we want to give it an action, we go to events. What happens when the action gets executed? Then you click on component and name it something action insert. Insert, we can give it the insert label. Name it command button insert. Then we export the dialogue. Okay, we can try to build this again. The dialogue should be updated now. I will try to clean my user profile. Don't know what this, okay, we'll try again. Build the extension. So we have it there but it's not active. Now it is. Yeah, there we go. There's the dialogue. You can enter some text. Click the insert button. Okay, we haven't handled this method yet but we have handled the close button. Now if you want to handle the insert action, I would add a new action to the supported actions array. This is my action insert and I add it to this array. This is returned in the get supported method names. That's a method from the dialogue event handler and it tells the event handler that this action is supported by this handler. Then we do something with it here. Action, no, not action console, action insert. And we can try to read the text from the button we have there and not the button, the text field. Our text field was labeled. Let's check it. And look where's my dialogue. Yeah, it's labeled text field one. So I have the dialogue helper. There are some methods to get an edit field dialogue. So then we create this field and then in this case we want the text from that. Then we try to insert it into the document. I have some helper method somewhere. Yeah, I just copied this over. It's not yet in the starter project. Helper new Java class. Name it. How was it named? Document helper, okay. So this is where we don't need the rest also. Okay, then we use the document helper to get current document with the context. Where do we have the context there? Okay, that's our text document. So this is a small dive into the UNO API. It's very powerful. Text document.set, no, what's the method now? Get text.set string, is it this? I'm not completely sure. We can try it out. Okay, now I will start it in debug mode. Enter some text. Insert, okay, there it is. Some text. Now, if it wouldn't work, I would stick a break point in here. If I started with debug mode and I could enter some other text. And then this is really helpful. A lot of times you would need debugging. And you have no setup for the debugging. You just get there and have your usual Java debugger can inspect the variable as you're used to. Step through, et cetera. Okay, so we have some minutes left. There are some other stuff we could do. Are there any questions up to now? Hello, one question is there are many, many already existing Java extensions which are probably not created with this plugin. And the question is how hard it is to use this plugin for code that's basically written in an IDE agnostic way so that it doesn't have a matching Eclipse project and so on. Is it easy to import existing working Java code to into Eclipse and use this plugin with? Or that's a major pain. Yeah, good question. I'd say it depends whether the plugin expects a certain structure. But there are some things you can configure. So we can have a look how this looks like. There is mainly two configuration files which are used by Eclipse. Once the dot project file, this is the Eclipse project and the UNO project that is from the Eclipse extension and the dot project. Well, it's just an Eclipse project file which says I have this nature, the I'm in Eclipse core UNO nature. No, I'm in Java project and I'm in this plugin nature. So if you add that to your existing extension, Eclipse would recognize it as this extension should be handled by the Eclipse plugin. There's no automatic way of doing this but you can hack these config files. And then you would also need this extension, this config file, this is generated when you create a new extension, when you import an existing one, you would need to copy it over. And I think it's possible. I've not done it yet, but these are the two files you need to work with. Okay, we have. Sorry? I never questioned it. As I would have something else for the four minutes we have. So how does this extension show up in the menu and in the toolbar, just a quick look. We have the registry. This is mapped to the office configuration. It's the same, you can use the same files that are in the office configuration. Overwrite them here. Okay, addons.cu is the main user interface configuration file. There is a node office toolbar. There is, just define the toolbar we have. And this is the button on the toolbar. It has the URL, this calls our service, it's a starter project. And this is the parameter that goes into the trigger method. Action one, target is which frame it should target and the context in which modules it should appear. You can add a multiple context there so it appears in other modules as well. I'm out of time, thanks. Okay, and the same for the menu bar. You can have a look at that. And there's also accelerators. There the accelerators are defined and the window state, it says where the toolbar is. So that's the main configuration. Thank you.