Compare commits

..

31 commits

Author SHA1 Message Date
cb51dd940c Set main icon 2020-04-23 19:03:06 +02:00
7e85c01984 Update 0.4.1 2020-04-23 16:45:33 +02:00
e0302b1652 Icons 2020-04-23 16:44:01 +02:00
7d164e10a6 Modified metadata storage 2020-04-22 17:48:52 +02:00
7d66b8d73b Updated version 2020-04-20 13:56:21 +02:00
a199cf2734 Updated version 2020-04-20 13:56:13 +02:00
4152d529f7 Scrollable tables 2020-04-20 13:54:22 +02:00
7975e49b23 Wrap text in table 2020-04-20 12:55:54 +02:00
a19a037b52 Check updates 2020-04-17 11:49:08 +02:00
a557720a7b Updates testing 2020-04-17 11:44:47 +02:00
c48d6fd7a5 saved 2020-04-17 11:42:58 +02:00
0cc1b45261 Saved 2020-04-17 11:42:14 +02:00
9676a684e2 Added update xml path to description 2020-04-17 11:41:51 +02:00
32cd313260 Added release notes and update xml 2020-04-17 11:39:08 +02:00
26f9f880b5 Dispose one open second window 2020-04-17 11:30:24 +02:00
c1dc50aeaa Hide annotations 2020-04-16 22:25:07 +02:00
faa9cf856d Added popup menu and fixed NPE 2020-04-16 16:20:53 +02:00
90617b8120 Alpha working 2020-04-16 16:12:40 +02:00
adf19bc4ab Working on GUI 2020-04-16 14:08:29 +02:00
76859c54db End of the day commit 2020-04-15 19:53:47 +02:00
e7f4f3c46e Save annotation range in outline object 2020-04-15 16:19:03 +02:00
167555ebbe Read annotations content 2020-04-14 12:23:19 +02:00
da9eb999c1 Serialization 2020-04-09 17:16:38 +02:00
cebf79d67e Adding tabs for outline 2020-04-09 15:38:37 +02:00
71776fa54b Working on outline metadata 2020-04-09 15:03:47 +02:00
c37b01eb92 Added some translations 2020-04-08 17:42:48 +02:00
be4279323e Reverted dialog removal 2020-04-08 17:30:25 +02:00
620425f43d Renamings 2020-04-08 17:15:57 +02:00
79c0051ee5 Removed menu 2020-04-08 16:43:04 +02:00
425bd82592 Works for document properties. 2020-04-08 13:42:49 +02:00
f9a9aefc72 GUI working 2020-04-07 18:09:17 +02:00
44 changed files with 1638 additions and 490 deletions

View file

@ -3,6 +3,10 @@
<classpathentry kind="src" path="source"/> <classpathentry kind="src" path="source"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="build"/> <classpathentry kind="lib" path="build"/>
<classpathentry kind="con" path="org.libreoffice.ide.eclipse.java.OOO_CONTAINER/LibreOffice 5.0"/> <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
<classpathentry kind="lib" path="miglayout15-swing.jar" sourcepath="miglayout-src.zip"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/JSON"/>
<classpathentry kind="lib" path="json-20190722.jar"/>
<classpathentry kind="con" path="org.libreoffice.ide.eclipse.java.OOO_CONTAINER/LibreOffice 6.3 #1"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>StarterProject</name> <name>Metadata Editor</name>
<comment></comment> <comment></comment>
<projects> <projects>
</projects> </projects>

View file

@ -1,10 +1,10 @@
#UNO project configuration file #UNO project configuration file
#Tue Apr 05 17:37:26 CEST 2016 #Fri Apr 10 17:20:27 CEST 2020
project.srcdir=/source project.srcdir=/source
regclassname=org.libreoffice.example.comp.RegistrationHandler regclassname=pro.litvinovg.libreoffice.metadata.RegistrationHandler
javaversion=java5 javaversion=java5
project.sdk=5.0.5.2 project.sdk=6.3.5.2
project.ooo=LibreOffice 5.0 project.ooo=LibreOffice 6.3 \#1
project.implementation=comp project.implementation=comp
project.build=build project.build=build
project.language=Java project.language=Java

View file

@ -1,35 +1 @@
# LibreOffice Starter Extension Metadata editor extension
This repository contains some boilerplate code and config you need to get started to build your own LibreOffice Extension.
You can use this project as a starting point to write your own extension for LibreOffice.
## Get started
1. Install [LibreOffice](http://www.libreoffice.org/download) & the [LibreOffice SDK](http://www.libreoffice.org/download) (5.0 or greater)
2. Install [Eclipse](http://www.eclipse.org/) IDE for Java Developers & the [LOEclipse plugin](https://marketplace.eclipse.org/content/loeclipse)
3. [Download](https://github.com/smehrbrodt/libreoffice-starter-extension/archive/master.zip) this starter project & unzip it
4. Import the project in Eclipse (File->Import->Existing Projects into Workspace)
5. Let Eclipse know the paths to LibreOffice & the SDK (Project->Properties->LibreOffice Properties)
6. Setup Run Configuration
* Go to Run->Run Configurations
* Create a new run configuration of the type "LibreOffice Application"
* Select the project
* Run!
* *Hint: Show the error log to view the output of the run configuration (Window->Show View->Error Log)*
7. The extension will be installed in LibreOffice (see Tools->Extension Manager)
8. To launch the example dialog, click on the newly added toolbar/menu entry which have been added to Writer (named "Starter Project/Action One").
## Development Hints
* The entry point is in [StarterProjectImpl.java](https://github.com/smehrbrodt/libreoffice-starter-extension/blob/master/source/org/libreoffice/example/comp/StarterProjectImpl.java).
* Toolbar items and menu entries are defined in [Addons.xcu](https://github.com/smehrbrodt/libreoffice-starter-extension/blob/master/registry/org/openoffice/Office/Addons.xcu).
* Shortcuts are defined in [Accelerators.xcu](https://github.com/smehrbrodt/libreoffice-starter-extension/blob/master/registry/org/openoffice/Office/Accelerators.xcu).
* The position of the toolbar is defined in [WriterWindowState.xcu](https://github.com/smehrbrodt/libreoffice-starter-extension/blob/master/registry/org/openoffice/Office/UI/WriterWindowState.xcu).
* The dialog shown when clicking "Action One" is [ActionOneDialog.xdl](https://github.com/smehrbrodt/libreoffice-starter-extension/blob/master/dialog/ActionOneDialog.xdl). The dialog itself contains information how to edit it.
* The [DialogHelper](https://github.com/smehrbrodt/libreoffice-starter-extension/blob/master/source/org/libreoffice/example/helper/DialogHelper.java) contains some helper methods to work with the dialog.
* To debug the Java code, just stick a breakpoint anywhere in Eclipse and start your run configuration in debug mode.
* If you add non-code files (or an external .jar) to your extension, you need to mention them in [package.properties](https://github.com/smehrbrodt/libreoffice-starter-extension/blob/master/package.properties), else they won't be included in the packaged extension.
* Now go on customizing the extension to your needs. Some helpful links:
* [OpenOffice Wiki](https://wiki.openoffice.org/wiki/Extensions_development)
* [API Reference](http://api.libreoffice.org/docs/idl/ref/index.html)
* [Example extensions](http://api.libreoffice.org/examples/examples.html#Java_examples)

View file

@ -1,10 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:d="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink"> <description xmlns="http://openoffice.org/extensions/description/2006" xmlns:d="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink">
<identifier value="org.libreoffice.example.starterproject"/> <version value="0.4.1"/>
<version value="0.1"/> <identifier value="pro.litvinovg.libreoffice.metadata"/>
<update-information>
<src xlink:href="https://dev.litvinovg.pro/litvinovg/metadata-editor/-/raw/master/metadataeditor.update.xml"/>
</update-information>
<release-notes>
<src lang="en" xlink:href="releasenotes.txt"/>
</release-notes>
<display-name> <display-name>
<name lang="en">StarterProject</name> <name lang="en">MetadataEditor</name>
</display-name> </display-name>
<icon>
<default xlink:href="images/metadata.png"/>
<high-contrast xlink:href="images/metadata.png"/>
</icon>
<extension-description> <extension-description>
<src lang="en" xlink:href="description/desc_en.txt"/> <src lang="en" xlink:href="description/desc_en.txt"/>
</extension-description> </extension-description>

View file

@ -1 +1 @@
LibreOffice Starter Project Metadata editor for LibreOffice

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 575 B

12
metadataeditor.update.xml Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<description xmlns="http://openoffice.org/extensions/update/2006"
xmlns:xlink="http://www.w3.org/1999/xlink">
<identifier value="pro.litvinovg.libreoffice.metadata"/>
<version value="0.4.1" />
<update-download>
<src xlink:href="https://dev.litvinovg.pro/litvinovg/metadata-editor/uploads/cc4bd54cbaf865b21ca4f6b7dbda2e7b/Metadata_Editor.oxt" />
</update-download>
<release-notes>
<src xlink:href="https://dev.litvinovg.pro/litvinovg/metadata-editor/-/raw/master/releasenotes.txt" lang="en" />
</release-notes>
</description>

View file

@ -1,3 +1,3 @@
#Written by the OOEclipseIntegration #Written by the OOEclipseIntegration
#Thu Apr 07 11:36:27 CEST 2016 #Fri Apr 10 17:15:09 CEST 2020
contents=description, description/desc_en.txt, dialog, dialog/ActionOneDialog.xdl, images, images/actionOne_16.png, images/actionOne_26.png, registry, registry/org, registry/org/openoffice, registry/org/openoffice/Office, registry/org/openoffice/Office/Accelerators.xcu, registry/org/openoffice/Office/Addons.xcu, registry/org/openoffice/Office/UI, registry/org/openoffice/Office/UI/WriterWindowState.xcu contents=description, description/desc_en.txt, releasenotes.txt, images, images/actionOne_16.png, images/actionOne_26.png, json-20190722.jar, registry, registry/org, registry/org/openoffice, registry/org/openoffice/Office, registry/org/openoffice/Office/Accelerators.xcu, registry/org/openoffice/Office/Addons.xcu, registry/org/openoffice/Office/UI, registry/org/openoffice/Office/UI/WriterWindowState.xcu

View file

@ -7,7 +7,7 @@
<node oor:name="com.sun.star.text.TextDocument"> <node oor:name="com.sun.star.text.TextDocument">
<node oor:name="1_SHIFT_MOD1" oor:op="replace"> <node oor:name="1_SHIFT_MOD1" oor:op="replace">
<prop oor:name="Command"> <prop oor:name="Command">
<value xml:lang="en-US">service:org.libreoffice.example.StarterProject?actionOne</value> <value xml:lang="en-US">service:pro.litvinovg.libreoffice.MetadataEditor?openGUI</value>
</prop> </prop>
</node> </node>
</node> </node>

View file

@ -1,32 +1,30 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<oor:component-data oor:package="org.openoffice.Office" oor:name="Addons" <oor:component-data oor:package="org.openoffice.Office" oor:name="Addons"
xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema"> xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<node oor:name="AddonUI"> <node oor:name="AddonUI">
<node oor:name="Images"> <node oor:name="Images">
<node oor:name="org.libreoffice.example.StarterProject.imageActionOne" oor:op="replace"> <node oor:name="pro.litvinovg.libreoffice.metadata.openGUIImage" oor:op="replace">
<prop oor:name="URL" oor:type="xs:string"> <prop oor:name="URL" oor:type="xs:string">
<value>service:org.libreoffice.example.StarterProject?actionOne</value> <value>service:pro.litvinovg.libreoffice.MetadataEditor?openGUI</value>
</prop> </prop>
<node oor:name="UserDefinedImages"> <node oor:name="UserDefinedImages">
<prop oor:name="ImageSmallURL"> <prop oor:name="ImageBigURL">
<value>vnd.sun.star.extension://org.libreoffice.example.starterproject/images/actionOne_16.png</value> <value>vnd.sun.star.extension://pro.litvinovg.libreoffice.metadata/images/metadata.png</value>
</prop>
<prop oor:name="ImageBigURL">
<value>vnd.sun.star.extension://org.libreoffice.example.starterproject/images/actionOne_26.png</value>
</prop> </prop>
</node> </node>
</node> </node>
</node> </node>
<node oor:name="OfficeToolBar"> <node oor:name="OfficeToolBar">
<node oor:name="org.libreoffice.example.StarterProject.toolbar" oor:op="replace"> <node oor:name="pro.litvinovg.libreoffice.MetadataEditor.toolbar" oor:op="replace">
<prop oor:name="Title" oor:type="xs:string"> <prop oor:name="Title" oor:type="xs:string">
<value>Starter Project</value> <value>Starter Project</value>
</prop> </prop>
<prop oor:name="Docked" oor:op="fuse"><value>true</value></prop>
<node oor:name="t01" oor:op="replace"> <node oor:name="t01" oor:op="replace">
<prop oor:name="URL" oor:type="xs:string"> <prop oor:name="URL" oor:type="xs:string">
<value>service:org.libreoffice.example.StarterProject?actionOne</value> <value>service:pro.litvinovg.libreoffice.MetadataEditor?openGUI</value>
</prop> </prop>
<prop oor:name="Target" oor:type="xs:string"> <prop oor:name="Target" oor:type="xs:string">
<value>_self</value> <value>_self</value>
@ -35,35 +33,14 @@
<value>com.sun.star.text.TextDocument</value> <value>com.sun.star.text.TextDocument</value>
</prop> </prop>
<prop oor:name="Title" oor:type="xs:string"> <prop oor:name="Title" oor:type="xs:string">
<value xml:lang="en-US">Action One</value> <value xml:lang="en-US">Open metadata editor GUI</value>
<value xml:lang="ru-RU">Открыть редактор метаданных</value>
</prop> </prop>
</node> </node>
</node> </node>
</node> </node>
<node oor:name="OfficeMenuBar">
<node oor:name="org.libreoffice.example.StarterProject.menubar" oor:op="replace">
<prop oor:name="Title" oor:type="xs:string">
<value xml:lang="en-US">Starter Project</value>
</prop>
<prop oor:name="Context" oor:type="xs:string">
<value>com.sun.star.text.TextDocument</value>
</prop>
<node oor:name="Submenu">
<node oor:name="M1" oor:op="replace">
<prop oor:name="Title">
<value xml:lang="en-US">Action One</value>
</prop>
<prop oor:name="URL">
<value>service:org.libreoffice.example.StarterProject?actionOne</value>
</prop>
<prop oor:name="Target" oor:type="xs:string">
<value>_self</value>
</prop>
</node>
</node>
</node>
</node>
</node> </node>
</oor:component-data> </oor:component-data>

View file

@ -6,9 +6,10 @@
<node oor:name="UIElements"> <node oor:name="UIElements">
<node oor:name="States"> <node oor:name="States">
<!-- Used to dock the toolbar in the first toolbar row (by default it's floating) --> <!-- Used to dock the toolbar in the first toolbar row (by default it's floating) -->
<node oor:name="private:resource/toolbar/addon_org.libreoffice.example.StarterProject.toolbar" oor:op="replace"> <node oor:name="private:resource/toolbar/addon_pro.litvinovg.libreoffice.MetadataEditor.toolbar" oor:op="replace">
<prop oor:name="UIName" oor:type="xs:string"> <prop oor:name="UIName" oor:type="xs:string">
<value>Aktensystem</value> <value xml:lang="en">Metadata editor</value>
<value xml:lang="ru">Редактор метаданных</value>
</prop> </prop>
<prop oor:name="DockPos" oor:type="xs:string"> <prop oor:name="DockPos" oor:type="xs:string">
<value>10,0</value> <value>10,0</value>

1
releasenotes.txt Normal file
View file

@ -0,0 +1 @@
0.3.1 Alpha version

View file

@ -1 +0,0 @@
org.libreoffice.example.comp.StarterProjectImpl

View file

@ -1,76 +0,0 @@
package org.libreoffice.example.comp;
import com.sun.star.uno.XComponentContext;
import com.sun.star.lib.uno.helper.Factory;
import org.libreoffice.example.dialog.ActionOneDialog;
import org.libreoffice.example.helper.DialogHelper;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.lib.uno.helper.WeakBase;
public final class StarterProjectImpl extends WeakBase
implements com.sun.star.lang.XServiceInfo,
com.sun.star.task.XJobExecutor
{
private final XComponentContext m_xContext;
private static final String m_implementationName = StarterProjectImpl.class.getName();
private static final String[] m_serviceNames = {
"org.libreoffice.example.StarterProject" };
public StarterProjectImpl( XComponentContext context )
{
m_xContext = context;
};
public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) {
XSingleComponentFactory xFactory = null;
if ( sImplementationName.equals( m_implementationName ) )
xFactory = Factory.createComponentFactory(StarterProjectImpl.class, m_serviceNames);
return xFactory;
}
public static boolean __writeRegistryServiceInfo( XRegistryKey xRegistryKey ) {
return Factory.writeRegistryServiceInfo(m_implementationName,
m_serviceNames,
xRegistryKey);
}
// com.sun.star.lang.XServiceInfo:
public String getImplementationName() {
return m_implementationName;
}
public boolean supportsService( String sService ) {
int len = m_serviceNames.length;
for( int i=0; i < len; i++) {
if (sService.equals(m_serviceNames[i]))
return true;
}
return false;
}
public String[] getSupportedServiceNames() {
return m_serviceNames;
}
// com.sun.star.task.XJobExecutor:
public void trigger(String action)
{
switch (action) {
case "actionOne":
ActionOneDialog actionOneDialog = new ActionOneDialog(m_xContext);
actionOneDialog.show();
break;
default:
DialogHelper.showErrorMessage(m_xContext, null, "Unknown action: " + action);
}
}
}

View file

@ -1,43 +0,0 @@
package org.libreoffice.example.dialog;
import org.libreoffice.example.helper.DialogHelper;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XDialogEventHandler;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.uno.XComponentContext;
public class ActionOneDialog implements XDialogEventHandler {
private XDialog dialog;
private static final String actionOk = "actionOk";
private String[] supportedActions = new String[] { actionOk };
public ActionOneDialog(XComponentContext xContext) {
this.dialog = DialogHelper.createDialog("ActionOneDialog.xdl", xContext, this);
}
public void show() {
dialog.execute();
}
private void onOkButtonPressed() {
dialog.endExecute();
}
@Override
public boolean callHandlerMethod(XDialog dialog, Object eventObject, String methodName) throws WrappedTargetException {
if (methodName.equals(actionOk)) {
onOkButtonPressed();
return true; // Event was handled
}
return false; // Event was not handled
}
@Override
public String[] getSupportedMethodNames() {
return supportedActions;
}
}

View file

@ -1,184 +0,0 @@
package org.libreoffice.example.helper;
import java.io.File;
import com.sun.star.awt.MessageBoxType;
import com.sun.star.awt.Point;
import com.sun.star.awt.XButton;
import com.sun.star.awt.XComboBox;
import com.sun.star.awt.XControl;
import com.sun.star.awt.XControlContainer;
import com.sun.star.awt.XControlModel;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XDialogEventHandler;
import com.sun.star.awt.XDialogProvider2;
import com.sun.star.awt.XFixedText;
import com.sun.star.awt.XListBox;
import com.sun.star.awt.XMessageBox;
import com.sun.star.awt.XMessageBoxFactory;
import com.sun.star.awt.XTextComponent;
import com.sun.star.awt.XToolkit;
import com.sun.star.awt.XWindow;
import com.sun.star.awt.XWindowPeer;
import com.sun.star.beans.PropertyVetoException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
public class DialogHelper {
/**
* Create a dialog from an xdl file.
*
* @param xdlFile
* The filename in the `dialog` folder
* @param context
* @return XDialog
*/
public static XDialog createDialog(String xdlFile, XComponentContext context, XDialogEventHandler handler) {
Object oDialogProvider;
try {
oDialogProvider = context.getServiceManager().createInstanceWithContext("com.sun.star.awt.DialogProvider2",
context);
XDialogProvider2 xDialogProv = (XDialogProvider2) UnoRuntime.queryInterface(XDialogProvider2.class,
oDialogProvider);
File dialogFile = FileHelper.getDialogFilePath(xdlFile, context);
return xDialogProv.createDialogWithHandler(convertToURL(context, dialogFile), handler);
} catch (Exception e) {
return null;
}
}
/** Returns a URL to be used with XDialogProvider to create a dialog */
public static String convertToURL(XComponentContext xContext, File dialogFile) {
String sURL = null;
try {
com.sun.star.ucb.XFileIdentifierConverter xFileConverter = (com.sun.star.ucb.XFileIdentifierConverter) UnoRuntime
.queryInterface(com.sun.star.ucb.XFileIdentifierConverter.class, xContext.getServiceManager()
.createInstanceWithContext("com.sun.star.ucb.FileContentProvider", xContext));
sURL = xFileConverter.getFileURLFromSystemPath("", dialogFile.getAbsolutePath());
} catch (com.sun.star.uno.Exception ex) {
return null;
}
return sURL;
}
/** Returns a button (XButton) from a dialog */
public static XButton getButton(XDialog dialog, String componentId) {
XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
dialog);
Object control = xDlgContainer.getControl(componentId);
return (XButton) UnoRuntime.queryInterface(XButton.class, control);
}
/** Returns a text field (XTextComponent) from a dialog */
public static XTextComponent getEditField(XDialog dialog, String componentId) {
XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
dialog);
Object control = xDlgContainer.getControl(componentId);
return (XTextComponent) UnoRuntime.queryInterface(XTextComponent.class, control);
}
/** Returns a Combo box (XComboBox) from a dialog */
public static XComboBox getCombobox(XDialog dialog, String componentId) {
XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
dialog);
Object control = xDlgContainer.getControl(componentId);
return (XComboBox) UnoRuntime.queryInterface(XComboBox.class, control);
}
/** Returns a List box (XListBox) from a dialog */
public static XListBox getListBox(XDialog dialog, String componentId) {
XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
dialog);
Object control = xDlgContainer.getControl(componentId);
return (XListBox) UnoRuntime.queryInterface(XListBox.class, control);
}
/** Returns a label (XFixedText) from a dialog */
public static XFixedText getLabel(XDialog dialog, String componentId) {
XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
dialog);
Object control = xDlgContainer.getControl(componentId);
return (XFixedText) UnoRuntime.queryInterface(XFixedText.class, control);
}
public static void EnableButton(XDialog dialog, String componentId, boolean enable) {
XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
dialog);
// retrieve the control that we want to disable or enable
XControl xControl = UnoRuntime.queryInterface(XControl.class, xDlgContainer.getControl(componentId));
XPropertySet xModelPropertySet = UnoRuntime.queryInterface(XPropertySet.class, xControl.getModel());
try {
xModelPropertySet.setPropertyValue("Enabled", Boolean.valueOf(enable));
} catch (IllegalArgumentException | UnknownPropertyException | PropertyVetoException
| WrappedTargetException e) {
return;
}
}
/** Set the focus to an input field */
public static void SetFocus(XTextComponent editField) {
XWindow xControlWindow = UnoRuntime.queryInterface(XWindow.class, editField);
xControlWindow.setFocus();
}
public static void setPosition(XDialog dialog, int posX, int posY) {
XControlModel xDialogModel = UnoRuntime.queryInterface(XControl.class, dialog).getModel();
XPropertySet xPropSet = UnoRuntime.queryInterface(XPropertySet.class, xDialogModel);
try {
xPropSet.setPropertyValue("PositionX", posX);
xPropSet.setPropertyValue("PositionY", posY);
} catch (com.sun.star.lang.IllegalArgumentException | UnknownPropertyException | PropertyVetoException
| WrappedTargetException e) {
return;
}
}
public static Point getPosition(XDialog dialog) {
int posX = 0;
int posY = 0;
XControlModel xDialogModel = UnoRuntime.queryInterface(XControl.class, dialog).getModel();
XPropertySet xPropSet = UnoRuntime.queryInterface(XPropertySet.class, xDialogModel);
try {
posX = (int) xPropSet.getPropertyValue("PositionX");
posY = (int) xPropSet.getPropertyValue("PositionY");
} catch (UnknownPropertyException | WrappedTargetException e) {
}
return new Point(posX, posY);
}
public static void showInfoMessage(XComponentContext context, XDialog dialog, String message) {
showMessageBox(context, dialog, MessageBoxType.INFOBOX, "Info", message);
}
public static void showWarningMessage(XComponentContext context, XDialog dialog, String message) {
showMessageBox(context, dialog, MessageBoxType.WARNINGBOX, "Warnung", message);
}
public static void showErrorMessage(XComponentContext context, XDialog dialog, String message) {
showMessageBox(context, dialog, MessageBoxType.ERRORBOX, "Fehler", message);
}
public static void showMessageBox(XComponentContext context, XDialog dialog, MessageBoxType type, String sTitle, String sMessage) {
XToolkit xToolkit;
try {
xToolkit = UnoRuntime.queryInterface(XToolkit.class,
context.getServiceManager().createInstanceWithContext("com.sun.star.awt.Toolkit", context));
} catch (Exception e) {
return;
}
XMessageBoxFactory xMessageBoxFactory = UnoRuntime.queryInterface(XMessageBoxFactory.class, xToolkit);
XWindowPeer xParentWindowPeer = UnoRuntime.queryInterface(XWindowPeer.class, dialog);
XMessageBox xMessageBox = xMessageBoxFactory.createMessageBox(xParentWindowPeer, type,
com.sun.star.awt.MessageBoxButtons.BUTTONS_OK, sTitle, sMessage);
if (xMessageBox == null)
return;
xMessageBox.execute();
}
}

View file

@ -1,42 +0,0 @@
package org.libreoffice.example.helper;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XFrame;
import com.sun.star.frame.XModel;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.text.XTextDocument;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
public class DocumentHelper {
/** Returns the curerent XDesktop */
public static XDesktop getCurrentDesktop(XComponentContext xContext) {
XMultiComponentFactory xMCF = (XMultiComponentFactory) UnoRuntime.queryInterface(XMultiComponentFactory.class,
xContext.getServiceManager());
Object desktop = null;
try {
desktop = xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", xContext);
} catch (Exception e) {
return null;
}
return (XDesktop) UnoRuntime.queryInterface(com.sun.star.frame.XDesktop.class, desktop);
}
/** Returns the current XComponent */
private static XComponent getCurrentComponent(XComponentContext xContext) {
return (XComponent) getCurrentDesktop(xContext).getCurrentComponent();
}
/** Returns the current frame */
public static XFrame getCurrentFrame(XComponentContext xContext) {
XModel xModel = (XModel) UnoRuntime.queryInterface(XModel.class, getCurrentComponent(xContext));
return xModel.getCurrentController().getFrame();
}
/** Returns the current text document (if any) */
public static XTextDocument getCurrentDocument(XComponentContext xContext) {
return (XTextDocument) UnoRuntime.queryInterface(XTextDocument.class, getCurrentComponent(xContext));
}
}

View file

@ -1,59 +0,0 @@
package org.libreoffice.example.helper;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import com.sun.star.deployment.PackageInformationProvider;
import com.sun.star.deployment.XPackageInformationProvider;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.XURLTransformer;
public class FileHelper {
final static String DIALOG_RESOURCES = "dialog/";
/**
* Returns a path to a dialog file
*/
public static File getDialogFilePath(String xdlFile, XComponentContext xContext) {
return getFilePath(DIALOG_RESOURCES + xdlFile, xContext);
}
/**
* Returns a file path for a file in the installed extension, or null on failure.
*/
public static File getFilePath(String file, XComponentContext xContext) {
XPackageInformationProvider xPackageInformationProvider = PackageInformationProvider.get(xContext);
String location = xPackageInformationProvider.getPackageLocation("org.libreoffice.example.starterproject");
Object oTransformer;
try {
oTransformer = xContext.getServiceManager().createInstanceWithContext("com.sun.star.util.URLTransformer", xContext);
} catch (Exception e) {
e.printStackTrace();
return null;
}
XURLTransformer xTransformer = (XURLTransformer)UnoRuntime.queryInterface(XURLTransformer.class, oTransformer);
com.sun.star.util.URL[] oURL = new com.sun.star.util.URL[1];
oURL[0] = new com.sun.star.util.URL();
oURL[0].Complete = location + "/" + file;
xTransformer.parseStrict(oURL);
URL url;
try {
url = new URL(oURL[0].Complete);
} catch (MalformedURLException e1) {
return null;
}
File f;
try {
f = new File(url.toURI());
} catch (URISyntaxException e1) {
return null;
}
return f;
}
}

View file

@ -0,0 +1,6 @@
package pro.litvinovg.libreoffice;
public interface DocumentParser {
public void parse();
}

View file

@ -0,0 +1,90 @@
package pro.litvinovg.libreoffice;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.NoSuchElementException;
import com.sun.star.container.XEnumeration;
import com.sun.star.container.XEnumerationAccess;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.table.XCell;
import com.sun.star.text.XText;
import com.sun.star.text.XTextContent;
import com.sun.star.text.XTextRange;
import com.sun.star.text.XTextTable;
import com.sun.star.uno.UnoRuntime;
public class DocumentParserImpl implements DocumentParser{
XText text = null;
protected XTextRange documentEnd = null;
public DocumentParserImpl(XText text) {
super();
this.text = text;
}
public void parse() {
parseText(text);
}
protected void parseText(XText curText) {
XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, curText);
XEnumeration textEnum = enumAccess.createEnumeration();
while (textEnum.hasMoreElements()) {
try {
XTextContent textContent = UnoRuntime.queryInterface(XTextContent.class, textEnum.nextElement());
documentEnd = textContent.getAnchor().getEnd();
if(isSupported(textContent, "com.sun.star.text.TextTable")) {
parseTable(textContent);
} else
if (isSupported(textContent, "com.sun.star.style.ParagraphProperties")) {
parseParagraph(textContent);
}
} catch (NoSuchElementException e) {
e.printStackTrace();
} catch (WrappedTargetException e) {
e.printStackTrace();
}
}
}
private void parseTable(XTextContent textContent) {
XTextTable table = UnoRuntime.queryInterface(XTextTable.class, textContent);
String[] cellNames = table.getCellNames();
for (String cellName : cellNames) {
XCell cell = table.getCellByName(cellName);
XText cellText = UnoRuntime.queryInterface(XText.class, cell);
cellText.getText();
parseText(cellText);
}
}
private void parseParagraph(XTextContent textContent) {
XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, textContent);
paraProperties(properties, textContent);
XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, textContent);
XEnumeration paraEnum = enumAccess.createEnumeration();
while (paraEnum.hasMoreElements()) {
try {
XPropertySet portionPoperties = UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, paraEnum.nextElement());
portionProperties(portionPoperties, textContent);
} catch (NoSuchElementException e) {
e.printStackTrace();
} catch (WrappedTargetException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void portionProperties(XPropertySet portionPoperties, XTextContent textContent) {
}
protected void paraProperties(XPropertySet properties,XTextContent textContent) {
}
private boolean isSupported(Object object, String service) {
XServiceInfo info = UnoRuntime.queryInterface(XServiceInfo.class, object);
if (info == null) {
return false;
}
return info.supportsService(service);
}
}

View file

@ -0,0 +1,47 @@
package pro.litvinovg.libreoffice;
import static pro.litvinovg.libreoffice.metadata.Document.METADATA_EXTENSION;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.NoSuchElementException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.text.XText;
import com.sun.star.text.XTextContent;
import com.sun.star.text.XTextField;
import com.sun.star.text.XTextRange;
import com.sun.star.uno.UnoRuntime;
public class MetadataCleaner extends DocumentParserImpl {
public MetadataCleaner(XText text) {
super(text);
}
@Override
public void portionProperties(XPropertySet portionPoperties, XTextContent textContent) {
String portionType = null;
try {
portionType = (String) portionPoperties.getPropertyValue("TextPortionType");
if (portionType != null && portionType.equals("Annotation")) {
Object annotation = portionPoperties.getPropertyValue("TextField");
XPropertySet annotationProperties = UnoRuntime.queryInterface(XPropertySet.class, annotation);
String author = (String) annotationProperties.getPropertyValue("Author");
if (author != null && author.equals(METADATA_EXTENSION)) {
XTextRange anchor = textContent.getAnchor();
XText curText = anchor.getText();
XTextField textField = UnoRuntime.queryInterface(XTextField.class, annotation);
try {
curText.removeTextContent( textField );
} catch (NoSuchElementException e) {
e.printStackTrace();
}
}
}
} catch (UnknownPropertyException e) {
e.printStackTrace();
} catch (WrappedTargetException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,72 @@
package pro.litvinovg.libreoffice;
import java.util.ArrayList;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.text.XText;
import com.sun.star.text.XTextContent;
import com.sun.star.text.XTextRange;
import com.sun.star.uno.UnoRuntime;
import pro.litvinovg.libreoffice.metadata.OutlineElement;
import static pro.litvinovg.libreoffice.metadata.Document.*;
public class MetadataReader extends DocumentParserImpl {
private ArrayList<OutlineElement> outline;
private boolean firstPara = true;
public MetadataReader(XText text, ArrayList<OutlineElement> outline) {
super(text);
this.outline = outline;
}
@Override
public void parse() {
parseText(text);
OutlineElement lastElement = outline.get(outline.size()-1);
}
@Override
public void portionProperties(XPropertySet portionPoperties, XTextContent textContent) {
String portionType = null;
try {
portionType = (String) portionPoperties.getPropertyValue("TextPortionType");
if (portionType != null && portionType.equals("Annotation")) {
Object annotation = portionPoperties.getPropertyValue("TextField");
XPropertySet annotationProperties = UnoRuntime.queryInterface(XPropertySet.class, annotation);
String author = (String) annotationProperties.getPropertyValue("Author");
if (author != null && author.equals(METADATA_EXTENSION)) {
String content = (String) annotationProperties.getPropertyValue("Content");
OutlineElement lastElement = outline.get(outline.size()-1);
lastElement.readMetadata(content);
}
}
} catch (UnknownPropertyException e) {
e.printStackTrace();
} catch (WrappedTargetException e) {
e.printStackTrace();
}
}
@Override
protected void paraProperties(XPropertySet properties, XTextContent textContent) {
Short outlineLevel = null;
try {
outlineLevel = (Short) properties.getPropertyValue("OutlineLevel");
} catch (UnknownPropertyException e) {
e.printStackTrace();
} catch (WrappedTargetException e) {
e.printStackTrace();
}
if (firstPara || (outlineLevel != null && outlineLevel > 0)) {
XTextRange textRange = textContent.getAnchor();
if (firstPara) {
outline.add(new OutlineElement(textRange, "Документ"));
firstPara = false;
} else {
outline.add(new OutlineElement(textRange, textRange.getString()));
}
}
}
}

View file

@ -0,0 +1,21 @@
package pro.litvinovg.libreoffice.metadata;
public class CustomDocumentProperty {
private String name;
private String value;
private String type;
public CustomDocumentProperty(String name, String value, String type) {
this.name = name;
this.value = value;
this.type = type;
}
public String getType() {
return type;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
}

View file

@ -0,0 +1,328 @@
package pro.litvinovg.libreoffice.metadata;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import com.sun.star.beans.IllegalTypeException;
import com.sun.star.beans.NotRemoveableException;
import com.sun.star.beans.Property;
import com.sun.star.beans.PropertyExistException;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.PropertyVetoException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertyContainer;
import com.sun.star.beans.XPropertySet;
import com.sun.star.beans.XPropertySetInfo;
import com.sun.star.document.XDocumentProperties;
import com.sun.star.document.XDocumentPropertiesSupplier;
import com.sun.star.frame.XController;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XDispatch;
import com.sun.star.frame.XDispatchHelper;
import com.sun.star.frame.XDispatchProvider;
import com.sun.star.frame.XFrame;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.text.XText;
import com.sun.star.text.XTextDocument;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.view.XViewSettingsSupplier;
import pro.litvinovg.libreoffice.DocumentParser;
import pro.litvinovg.libreoffice.MetadataCleaner;
import pro.litvinovg.libreoffice.MetadataReader;
public class Document {
private static final String DOC_AUTHOR = "Document author";
private static final String DOC_TITLE = "Document title";
private static final String DOC_SUBJECT = "Document subject";
private static final String DOC_DESCRIPTION = "Document description";
private static final String DOC_KEYWORDS = "Document keywords";
private static final short REMOVEABLE_ATTRIBUTE = 128;
public static final String METADATA_EXTENSION = "Metadata Extension";
private XComponentContext context;
private XDesktop xDesktop;
private XMultiComponentFactory multiComponentFactory;
private XMultiServiceFactory multiServiceFactory;
private XComponent currentDocument;
private XDocumentProperties documentProperties;
private XDocumentPropertiesSupplier documentPropertiesSupplier;
private XText text = null;
private ArrayList<OutlineElement> outline = new ArrayList<OutlineElement>();
private XFrame frame;
private XDispatchProvider dispatchProvider;
XTextDocument textDocument;
public Document(XComponentContext componentContext) {
context = componentContext;
multiComponentFactory = context.getServiceManager();
try {
Object oDesktop = multiComponentFactory.createInstanceWithContext("com.sun.star.frame.Desktop", context);
xDesktop = UnoRuntime.queryInterface(XDesktop.class, oDesktop);
getCurrentDocument();
getDocumentText();
multiServiceFactory = UnoRuntime.queryInterface(XMultiServiceFactory.class, currentDocument);
readMetadataInDocument();
frame = xDesktop.getCurrentFrame();
dispatchProvider = UnoRuntime.queryInterface( com.sun.star.frame.XDispatchProvider.class, frame );
hideAnnotations();
} catch (Exception e) {
System.out.println("xDesktop inaccessible. Can not proceed.");
e.printStackTrace();
System.exit(1);
}
}
private void getDocumentText() {
textDocument = UnoRuntime.queryInterface(XTextDocument.class,currentDocument);
text = textDocument.getText();
}
private void readMetadataInDocument() {
DocumentParser reader = new MetadataReader(text, outline);
reader.parse();
}
private void cleanMetadataInDocument() {
DocumentParser reader = new MetadataCleaner(text);
reader.parse();
}
public void writeOutlineMetadata() {
cleanMetadataInDocument();
for (OutlineElement element : outline){
if (!element.isEmpty()) {
Object annotation;
try {
annotation = multiServiceFactory.createInstance("com.sun.star.text.TextField.Annotation");
element.writeMetadata(annotation);
} catch (com.sun.star.uno.Exception e) {
e.printStackTrace();
}
}
}
}
private void getCurrentDocument() throws MetadataInaccessableException {
currentDocument = xDesktop.getCurrentComponent();
if (currentDocument == null) {
throw new MetadataInaccessableException("Could not access current document.");
}
}
public void logProperties() {
logDocumentProperties();
logDocumentCustomProperties();
}
public void setCustomDocumentProperties(ArrayList<CustomDocumentProperty> docCustomProps) {
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
removeStringProperties();
addStringProperties(docCustomProps);
}
private void addStringProperties(ArrayList<CustomDocumentProperty> docCustomProps) {
XPropertyContainer userDifinedProperties = documentProperties.getUserDefinedProperties();
for (int i = 0; i < docCustomProps.size();i++) {
CustomDocumentProperty property = docCustomProps.get(i);
try {
userDifinedProperties.addProperty(property.getName(), REMOVEABLE_ATTRIBUTE, property.getValue());
// System.out.println("added "+ property.getName() + " value " + property.getValue());
} catch (IllegalArgumentException e) {
System.out.println("IllegalArgumentException while adding new property");
e.printStackTrace();
} catch (PropertyExistException e) {
System.out.println("Property already exists");
e.printStackTrace();
} catch (IllegalTypeException e) {
System.out.println("Property type illegal");
e.printStackTrace();
}
}
}
private void removeStringProperties() {
XPropertyContainer userDifinedProperties = documentProperties.getUserDefinedProperties();
XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, userDifinedProperties);
if (propertySet != null) {
XPropertySetInfo propertySetInfo = propertySet.getPropertySetInfo();
if (propertySetInfo != null) {
Property[] props = propertySetInfo.getProperties();
for (Property prop : props) {
if (prop.Type.getTypeName().equals("string")){
try {
userDifinedProperties.removeProperty(prop.Name);
// System.out.println("removed "+ prop.Name);
} catch (UnknownPropertyException e) {
System.out.println("Property " + prop.Name + " does not exist.");
e.printStackTrace();
} catch (NotRemoveableException e) {
System.out.println("Property " + prop.Name + " is not removeable.");
e.printStackTrace();
}
}
}
}
}
}
public ArrayList<CustomDocumentProperty> getDocumentCustomProperties() {
ArrayList<CustomDocumentProperty> customProps = new ArrayList<CustomDocumentProperty>();
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
XPropertyContainer userDifinedProperties = documentProperties.getUserDefinedProperties();
XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, userDifinedProperties);
if (propertySet != null) {
XPropertySetInfo propertySetInfo = propertySet.getPropertySetInfo();
if (propertySetInfo != null) {
Property[] props = propertySetInfo.getProperties();
Arrays.sort(props, new Comparator<Property>() {
public int compare(Property p1, Property p2) {
return (p1.Name).compareTo(p2.Name);
}
});
for (Property prop : props) {
Object propValue = getProperty(propertySet, prop.Name);
if (prop.Type.getTypeName().equals("string")){
customProps.add(new CustomDocumentProperty(prop.Name, propValue.toString(), prop.Type.getTypeName()));
}
}
}
}
return customProps;
}
public Map<String, String> getDocumentProperties() {
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
Map<String, String> docProps = new HashMap<String, String>();
docProps.put(DOC_AUTHOR, documentProperties.getAuthor());
docProps.put(DOC_TITLE, documentProperties.getTitle());
docProps.put(DOC_SUBJECT, documentProperties.getSubject());
docProps.put(DOC_DESCRIPTION, documentProperties.getDescription());
String[] keywords = documentProperties.getKeywords();
StringBuilder keys = new StringBuilder();
for (int i = 0; i < keywords.length; i++) {
if (i > 0) {
keys.append(",");
}
keys.append(keywords[i]);
}
docProps.put(DOC_KEYWORDS, keys.toString());
return docProps;
}
public void setDocumentProperties(Map<String, String> docProps) {
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
if (docProps.containsKey(DOC_AUTHOR)) {
documentProperties.setAuthor(docProps.get(DOC_AUTHOR));
}
if (docProps.containsKey(DOC_TITLE)) {
documentProperties.setTitle(docProps.get(DOC_TITLE));
}
if (docProps.containsKey(DOC_SUBJECT)) {
documentProperties.setSubject(docProps.get(DOC_SUBJECT));
}
if (docProps.containsKey(DOC_DESCRIPTION)) {
documentProperties.setDescription(docProps.get(DOC_DESCRIPTION));
}
if (docProps.containsKey(DOC_KEYWORDS)) {
documentProperties.setKeywords(docProps.get(DOC_KEYWORDS).split(","));
}
}
private void logDocumentProperties() {
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
System.out.println(" Author: " + documentProperties.getAuthor());
System.out.println(" Title: " + documentProperties.getTitle());
System.out.println(" Subject: " + documentProperties.getSubject());
System.out.println(" Description: " + documentProperties.getDescription());
}
private void logDocumentCustomProperties() {
documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
documentProperties = documentPropertiesSupplier.getDocumentProperties();
XPropertyContainer userDifinedProperties = documentProperties.getUserDefinedProperties();
XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, userDifinedProperties);
if (propertySet != null) {
XPropertySetInfo propertySetInfo = propertySet.getPropertySetInfo();
if (propertySetInfo != null) {
Property[] props = propertySetInfo.getProperties();
Arrays.sort(props, new Comparator<Property>() {
public int compare(Property p1, Property p2) {
return (p1.Name).compareTo(p2.Name);
}
});
for (Property prop : props) {
Object propValue = getProperty(propertySet, prop.Name);
System.out.println(" " + prop.Name + ": " + prop.Type.getTypeName() + " == " + propValue);
}
}
}
}
private static Object getProperty(XPropertySet xProps, String propName) {
Object value = null;
try {
value = xProps.getPropertyValue(propName);
} catch (Exception e) {
System.out.println("Could not get property " + propName);
}
return value;
}
public ArrayList<OutlineElement> getOutline(){
return outline;
}
public void hideAnnotations() {
XController controller = textDocument.getCurrentController();
XViewSettingsSupplier viewSettings = UnoRuntime.queryInterface( XViewSettingsSupplier.class, controller);
XPropertySet properties = viewSettings.getViewSettings();
try {
properties.setPropertyValue("ShowAnnotations", false);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (UnknownPropertyException e) {
e.printStackTrace();
} catch (PropertyVetoException e) {
e.printStackTrace();
} catch (WrappedTargetException e) {
e.printStackTrace();
}
/*
* try { Object dispatchHelperObj =
* multiComponentFactory.createInstanceWithContext(
* "com.sun.star.frame.DispatchHelper", context); XDispatchHelper dispatchHelper
* = UnoRuntime.queryInterface( XDispatchHelper.class, dispatchHelperObj);
* PropertyValue empty = new PropertyValue(); PropertyValue[] array = new
* PropertyValue[] {empty}; XDispatchProvider dispatchProvider =
* UnoRuntime.queryInterface( XDispatchProvider.class, frame);
* dispatchHelper.executeDispatch(dispatchProvider, ".uno:ShowAnnotations", "",
* 0, array);
*
*
* } catch (com.sun.star.uno.Exception e) { e.printStackTrace(); }
*/
}
}

View file

@ -0,0 +1,21 @@
package pro.litvinovg.libreoffice.metadata;
public class MetadataElement {
private String name;
private String value;
public MetadataElement(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
}

View file

@ -0,0 +1,42 @@
package pro.litvinovg.libreoffice.metadata;
import java.util.Iterator;
import org.json.JSONException;
import org.json.JSONObject;
public class MetadataElementFactory {
public static final String METADATA_START = "## Metadata Editor extension. Outline metadata in JSON folllows:";
public static final String METADATA_PREFIX = "## ";
public static final String METADATA_END = "## Outline metadata finished.";
public static MetadataElement fromString(String cursorContent){
String data = cursorContent.substring(METADATA_PREFIX.length());
System.out.println("DATA " + data);
//TODO: Switch to Jackson or GSON
JSONObject json = new JSONObject(data);
Iterator<String> iterator = json.keys();
String name = iterator.next();
String value = json.getString(name);
return new MetadataElement(name, value);
}
public static String toString(MetadataElement element) {
JSONObject json = new JSONObject();
json.put(element.getName(), element.getValue());
return METADATA_PREFIX + json.toString();
}
public boolean isJSONValid(String test) {
try {
new JSONObject(test);
} catch (JSONException e) {
return false;
}
return true;
}
}

View file

@ -0,0 +1,98 @@
package pro.litvinovg.libreoffice.metadata;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import pro.litvinovg.libreoffice.metadata.views.EditorGUI;
import com.sun.star.lib.uno.helper.Factory;
import java.util.Arrays;
import java.util.Comparator;
import com.sun.star.beans.Property;
import com.sun.star.beans.XPropertyContainer;
import com.sun.star.beans.XPropertySet;
import com.sun.star.beans.XPropertySetInfo;
import com.sun.star.document.XDocumentProperties;
import com.sun.star.document.XDocumentPropertiesSupplier;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.lib.uno.helper.WeakBase;
public final class MetadataExtensionImpl extends WeakBase
implements com.sun.star.lang.XServiceInfo,
com.sun.star.task.XJobExecutor
{
private final XComponentContext context;
private XDesktop xDesktop;
private XMultiComponentFactory multiComponentFactory;
private XComponent currentDocument;
private XDocumentProperties documentProperties;
private XDocumentPropertiesSupplier documentPropertiesSupplier;
private static final String m_implementationName = MetadataExtensionImpl.class.getName();
private static final String[] m_serviceNames = { "pro.litvinovg.libreoffice.MetadataEditor" };
public MetadataExtensionImpl(XComponentContext componentContext) {
context = componentContext;
};
public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) {
XSingleComponentFactory xFactory = null;
if ( sImplementationName.equals( m_implementationName ) )
xFactory = Factory.createComponentFactory(MetadataExtensionImpl.class, m_serviceNames);
return xFactory;
}
public static boolean __writeRegistryServiceInfo( XRegistryKey xRegistryKey ) {
return Factory.writeRegistryServiceInfo(m_implementationName,
m_serviceNames,
xRegistryKey);
}
// com.sun.star.lang.XServiceInfo:
public String getImplementationName() {
return m_implementationName;
}
public boolean supportsService( String sService ) {
int len = m_serviceNames.length;
for( int i=0; i < len; i++) {
if (sService.equals(m_serviceNames[i]))
return true;
}
return false;
}
public String[] getSupportedServiceNames() {
return m_serviceNames;
}
// com.sun.star.task.XJobExecutor:
public void trigger(String action)
{
switch (action) {
case "openGUI":
Document doc = new Document(context);
EditorGUI.runGUI(doc);
break;
default:
}
}
}

View file

@ -0,0 +1,7 @@
package pro.litvinovg.libreoffice.metadata;
public class MetadataInaccessableException extends Exception {
public MetadataInaccessableException(String errorMessage) {
super(errorMessage);
}
}

View file

@ -0,0 +1,130 @@
package pro.litvinovg.libreoffice.metadata;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import org.json.JSONException;
import org.json.JSONObject;
import com.sun.star.beans.PropertyVetoException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.text.XText;
import com.sun.star.text.XTextCursor;
import com.sun.star.text.XTextField;
import com.sun.star.text.XTextRange;
import com.sun.star.uno.UnoRuntime;
import static pro.litvinovg.libreoffice.metadata.Document.*;
public class OutlineElement {
private String elementName;
private ArrayList<MetadataElement> metadata = null;
private XTextRange textRange;
public String getName() {
return elementName;
}
public boolean isEmpty() {
if (metadata.isEmpty()) {
return true;
}
for (int i = 0; i < metadata.size(); i++) {
if (!metadata.get(i).getName().isEmpty() && !metadata.get(i).getValue().isEmpty()) {
return false;
}
}
return true;
}
public OutlineElement(XTextRange textRange, String name) {
this.textRange = textRange;
this.elementName = name;
this.metadata = new ArrayList<MetadataElement>();
}
public Object[][] metadataToArray() {
Object [] [] result = null;
int size = metadata.size();
if (metadata.size() == 0) {
result = new Object[][] {
{"", ""},
{"", ""},
{"", ""},
};
} else {
result = new Object [size] [2];
for (int i = 0; i < size; i++) {
result[i][0] = metadata.get(i).getName();
result[i][1] = metadata.get(i).getValue();
}
}
return result;
}
public void readMetadata(String data) {
try {
JSONObject json = new JSONObject(data);
Set<String> nums = json.keySet();
for (String number : nums) {
JSONObject meta = (JSONObject) json.get(number);
Set<String> names = meta.keySet();
for (String name: names) {
String value = meta.getString(name);
metadata.add(new MetadataElement(name, value));
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private String metadataToString() {
JSONObject json = new JSONObject();
Integer i = 0;
for (MetadataElement element : metadata) {
String name = element.getName();
String value = element.getValue();
if (!name.isEmpty() && !value.isEmpty()) {
JSONObject meta = new JSONObject();
meta.put(element.getName(), element.getValue());
json.put(i.toString(), meta);
i++;
}
}
return json.toString();
}
public void writeMetadata(Object annotation) {
XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, annotation);
XText text = textRange.getText();
try {
properties.setPropertyValue("Author", METADATA_EXTENSION);
properties.setPropertyValue("Content", metadataToString());
XTextRange annotationRange = null;
annotationRange = textRange;
XTextField textField = UnoRuntime.queryInterface(XTextField.class, annotation);
text.insertTextContent( annotationRange, textField, false );
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (UnknownPropertyException e) {
e.printStackTrace();
} catch (PropertyVetoException e) {
e.printStackTrace();
} catch (WrappedTargetException e) {
e.printStackTrace();
}
}
public void setMetadata(ArrayList<MetadataElement> metadataInput) {
this.metadata.clear();
this.metadata.addAll(metadataInput);
}
}

View file

@ -0,0 +1 @@
pro.litvinovg.libreoffice.metadata.MetadataExtensionImpl

View file

@ -35,7 +35,7 @@
* *
* *
************************************************************************/ ************************************************************************/
package org.libreoffice.example.comp; package pro.litvinovg.libreoffice.metadata;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -0,0 +1,13 @@
package pro.litvinovg.libreoffice.metadata.tests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;
import pro.litvinovg.libreoffice.metadata.tests.uno.WriterTest;
import pro.litvinovg.libreoffice.metadata.tests.base.UnoSuite;
@RunWith(UnoSuite.class)
@SuiteClasses({WriterTest.class})
public class UnoTests {
}

View file

@ -0,0 +1,75 @@
package pro.litvinovg.libreoffice.metadata.tests.base;
import java.util.List;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
public class UnoSuite extends Suite {
private static XComponentContext componentContext;
public UnoSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
super(klass, builder);
}
public UnoSuite(RunnerBuilder builder, Class<?>[] classes) throws InitializationError {
super(builder, classes);
}
public UnoSuite(Class<?> klass, Class<?>[] suiteClasses) throws InitializationError {
super(klass, suiteClasses);
}
public UnoSuite(Class<?> klass, List<Runner> runners) throws InitializationError {
super(klass, runners);
}
public UnoSuite(RunnerBuilder builder, Class<?> klass, Class<?>[] suiteClasses) throws InitializationError {
super(builder, klass, suiteClasses);
}
@Override
public void run(RunNotifier arg0) {
try {
startOffice();
} catch (Exception e) {
e.printStackTrace();
}
super.run(arg0);
stopOffice();
}
private void startOffice() throws Exception {
componentContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
}
private void stopOffice() {
try {
if (componentContext != null) {
// Only the uno test suite which started the office can stop it
XMultiComponentFactory xMngr = componentContext.getServiceManager();
Object oDesktop = xMngr.createInstanceWithContext("com.sun.star.frame.Desktop", componentContext);
XDesktop xDesktop = (XDesktop)UnoRuntime.queryInterface(XDesktop.class, oDesktop);
xDesktop.terminate();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static XComponentContext getComponentContext() {
return componentContext;
}
}

View file

@ -0,0 +1,28 @@
package pro.litvinovg.libreoffice.metadata.tests.helper;
import com.sun.star.beans.PropertyValue;
import com.sun.star.frame.FrameSearchFlag;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.text.XTextDocument;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import pro.litvinovg.libreoffice.metadata.tests.base.UnoSuite;
public class UnoHelper {
public static XTextDocument getWriterDocument() throws Exception {
XMultiComponentFactory xMngr = UnoSuite.getComponentContext().getServiceManager();
Object oDesktop = xMngr.createInstanceWithContext("com.sun.star.frame.Desktop", UnoSuite.getComponentContext());
XComponentLoader xLoader = (XComponentLoader)UnoRuntime.queryInterface(
XComponentLoader.class, oDesktop);
XComponent xDoc = xLoader.loadComponentFromURL("private:factory/swriter", "_default",
FrameSearchFlag.ALL, new PropertyValue[0]);
return (XTextDocument)UnoRuntime.queryInterface(XTextDocument.class, xDoc);
}
}

View file

@ -0,0 +1,26 @@
package pro.litvinovg.libreoffice.metadata.tests.uno;
import static org.junit.Assert.assertNotNull;
import org.junit.Before;
import org.junit.Test;
import com.sun.star.text.XTextDocument;
import pro.litvinovg.libreoffice.metadata.tests.helper.UnoHelper;
public class WriterTest {
private XTextDocument xTextDocument;
@Before
public void setUp() throws Exception {
xTextDocument = UnoHelper.getWriterDocument();
}
@Test
public void test() {
assertNotNull(xTextDocument);
}
}

View file

@ -0,0 +1,449 @@
package pro.litvinovg.libreoffice.metadata.views;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridBagLayout;
import javax.swing.JCheckBox;
import java.awt.GridBagConstraints;
import javax.swing.JButton;
import java.awt.Insets;
import javax.swing.BoxLayout;
import javax.swing.UIManager;
import java.awt.Toolkit;
import javax.swing.JTabbedPane;
import java.awt.GridLayout;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JMenu;
import javax.swing.JTable;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import pro.litvinovg.libreoffice.metadata.CustomDocumentProperty;
import pro.litvinovg.libreoffice.metadata.Document;
import pro.litvinovg.libreoffice.metadata.OutlineElement;
import javax.swing.JScrollPane;
import javax.swing.JPopupMenu;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.JToggleButton;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JLabel;
import javax.swing.ScrollPaneConstants;
import java.awt.Dimension;
public class EditorGUI extends JFrame {
//Components
private JTable tableDocStandard;
private JTable tableDocCustom;
private ArrayList<MetadataTableModel> tableModels ;
//Component models
private DefaultTableModel docPropertiesModel;
private DefaultTableModel docCustomPropsModel;
private static JFrame singleFrame = null;
private Map<String, String> docProps;
private ArrayList<CustomDocumentProperty> docCustomProps;
private Document document = null;
private JButton btnSaveButton;
private JMenuItem menuItemPupupDocUserProps;
private ArrayList<OutlineElement> outline;
private JTabbedPane tabbedPane;
private JPanel panelStandardMetadata;
private JMenuBar menuBar;
/**
* Launch the application.
*/
public static void main(String[] args) {
testGUI();
}
public static void runGUI(Document doc) {
if (singleFrame != null) {
singleFrame.dispose();
}
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
EditorGUI frame = new EditorGUI(doc);
singleFrame = frame;
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private static void testGUI() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
EditorGUI frame = new EditorGUI();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public EditorGUI(Document doc) {
this.document = doc;
docProps = document.getDocumentProperties();
docCustomProps = document.getDocumentCustomProperties();
outline = document.getOutline();
tableModels = new ArrayList<MetadataTableModel>();
initComponents();
createEvents();
}
public EditorGUI() {
outline = new ArrayList<OutlineElement>();
initComponents();
createEvents();
}
private void createEvents() {
btnSaveButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveAction();
}
});
menuItemPupupDocUserProps.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
docCustomPropsModel.addRow(new Object[] {null, null});
}
});
}
private void updateDocCustomProps() {
Vector dataVector = docCustomPropsModel.getDataVector();
Enumeration elements = dataVector.elements();
docCustomProps.clear();
while (elements.hasMoreElements()) {
Vector row = (Vector) elements.nextElement();
String name = (String) row.get(0);
String value = (String) row.get(1);
if (!name.isEmpty() && !value.isEmpty()) {
docCustomProps.add(new CustomDocumentProperty(name, value, "string"));
}
}
}
private void updateDocProps() {
Vector dataVector = docPropertiesModel.getDataVector();
Enumeration elements = dataVector.elements();
docProps.clear();
while (elements.hasMoreElements()) {
Vector row = (Vector) elements.nextElement();
String name = (String) row.get(0);
String value = (String) row.get(1);
docProps.put(name, value);
}
}
private void initComponents() {
configureWindow();
panelStandardMetadata = new JPanel();
tabbedPane.addTab("Метаданные либры", null, panelStandardMetadata, null);
tabbedPane.setEnabledAt(0, true);
for (OutlineElement element : outline) {
addMetadataTab(element);
}
createDocPropsModel();
createCustomDocPropsModel();
tableDocStandard = new MetadataTable();
tableDocCustom = new MetadataTable();
configureTableDocStandard();
configureTableDocCustom();
btnSaveButton = new JButton("Сохранить");
GroupLayout gl_panelStandardMetadata = new GroupLayout(panelStandardMetadata);
configureGroupLayoutDoc(gl_panelStandardMetadata);
JPopupMenu popupMenu = new JPopupMenu();
addPopup(tableDocCustom, popupMenu);
menuItemPupupDocUserProps = new JMenuItem("Добавить строку");
popupMenu.add(menuItemPupupDocUserProps);
panelStandardMetadata.setLayout(gl_panelStandardMetadata);
menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu mnFile = new JMenu("Файл");
menuBar.add(mnFile);
}
private void addMetadataTab(OutlineElement element) {
JPanel panelOutline = new JPanel();
MetadataTableModel outlineTableModel = createOutlineTableModel(element);
tableModels.add(outlineTableModel);
JButton btnOutlineSave = new JButton("Сохранить");
btnOutlineSave.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveAction();
}
});
JScrollPane scrollPane = new JScrollPane();
scrollPane.setSize(new Dimension(50, 50));
JButton btnOutlineSave_1 = new JButton("Закрыть");
GroupLayout groupLayoutOutlineMetadata = new GroupLayout(panelOutline);
groupLayoutOutlineMetadata.setHorizontalGroup(
groupLayoutOutlineMetadata.createParallelGroup(Alignment.LEADING)
.addGroup(Alignment.TRAILING, groupLayoutOutlineMetadata.createSequentialGroup()
.addGroup(groupLayoutOutlineMetadata.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayoutOutlineMetadata.createSequentialGroup()
.addContainerGap(557, Short.MAX_VALUE)
.addComponent(btnOutlineSave_1, GroupLayout.PREFERRED_SIZE, 108, GroupLayout.PREFERRED_SIZE)
.addGap(104)
.addComponent(btnOutlineSave)
.addGap(32))
.addGroup(groupLayoutOutlineMetadata.createSequentialGroup()
.addGap(45)
.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 864, Short.MAX_VALUE)))
.addGap(90))
);
groupLayoutOutlineMetadata.setVerticalGroup(
groupLayoutOutlineMetadata.createParallelGroup(Alignment.LEADING)
.addGroup(Alignment.TRAILING, groupLayoutOutlineMetadata.createSequentialGroup()
.addContainerGap()
.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 600, Short.MAX_VALUE)
.addGap(31)
.addGroup(groupLayoutOutlineMetadata.createParallelGroup(Alignment.BASELINE)
.addComponent(btnOutlineSave_1)
.addComponent(btnOutlineSave))
.addGap(34))
);
JTable tableOutline = new MetadataTable();
scrollPane.setViewportView(tableOutline);
configureTableOutline(tableOutline, outlineTableModel);
JPopupMenu popupMenu = new JPopupMenu();
addPopup(tableOutline, popupMenu);
JMenuItem menuItem = new JMenuItem("Добавить строку");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
outlineTableModel.addRow(new Object[] {null, null});
}
});
popupMenu.add(menuItem);
panelOutline.setLayout(groupLayoutOutlineMetadata);
tabbedPane.addTab(element.getName(), null, panelOutline, null);
}
private void configureTableOutline(JTable tableOutline, DefaultTableModel outlineTableModel) {
tableOutline.setModel(outlineTableModel);
tableOutline.putClientProperty("terminateEditOnFocusLost", true);
tableOutline.setSurrendersFocusOnKeystroke(true);
tableOutline.setCellSelectionEnabled(true);
tableOutline.setFillsViewportHeight(true);
}
private void configureWindow() {
setIconImage(Toolkit.getDefaultToolkit().getImage(EditorGUI.class.getResource("/pro/litvinovg/libreoffice/metadata/resources/metadata.png")));
setTitle("Редактор метаданных");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 1170, 755);
getContentPane().setLayout(null);
getContentPane().setLayout(new GridLayout(0, 1, 0, 0));
tabbedPane = new JTabbedPane(JTabbedPane.LEFT, JTabbedPane.SCROLL_TAB_LAYOUT);
tabbedPane.setBounds(125, 138, 913, 546);
getContentPane().add(tabbedPane);
}
private void configureTableDocStandard() {
tableDocStandard.putClientProperty("terminateEditOnFocusLost", true);
tableDocStandard.setSurrendersFocusOnKeystroke(true);
tableDocStandard.setCellSelectionEnabled(true);
tableDocStandard.setFillsViewportHeight(true);
tableDocStandard.setModel(docPropertiesModel);
}
private void configureTableDocCustom() {
tableDocCustom.setColumnSelectionAllowed(true);
tableDocCustom.putClientProperty("terminateEditOnFocusLost", true);
tableDocCustom.setSurrendersFocusOnKeystroke(true);
tableDocCustom.setFillsViewportHeight(true);
tableDocCustom.setCellSelectionEnabled(true);
tableDocCustom.setModel(docCustomPropsModel);
}
private void configureGroupLayoutDoc(GroupLayout gl_panelStandardMetadata) {
JLabel labelDocProperties = new JLabel("Основные метаданные");
JLabel labelDocCustomProperties = new JLabel("Дополнительные метаданные");
gl_panelStandardMetadata.setHorizontalGroup(
gl_panelStandardMetadata.createParallelGroup(Alignment.TRAILING)
.addGroup(Alignment.LEADING, gl_panelStandardMetadata.createSequentialGroup()
.addGap(378)
.addComponent(labelDocProperties, GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE)
.addGap(421))
.addGroup(Alignment.LEADING, gl_panelStandardMetadata.createSequentialGroup()
.addContainerGap()
.addGroup(gl_panelStandardMetadata.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panelStandardMetadata.createSequentialGroup()
.addComponent(tableDocStandard, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE)
.addContainerGap())
.addGroup(Alignment.TRAILING, gl_panelStandardMetadata.createSequentialGroup()
.addComponent(btnSaveButton)
.addGap(154))))
.addGroup(Alignment.LEADING, gl_panelStandardMetadata.createSequentialGroup()
.addGap(350)
.addComponent(labelDocCustomProperties, GroupLayout.DEFAULT_SIZE, 233, Short.MAX_VALUE)
.addGap(381))
.addGroup(Alignment.LEADING, gl_panelStandardMetadata.createSequentialGroup()
.addContainerGap()
.addComponent(tableDocCustom, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE)
.addContainerGap())
);
gl_panelStandardMetadata.setVerticalGroup(
gl_panelStandardMetadata.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panelStandardMetadata.createSequentialGroup()
.addGap(53)
.addComponent(labelDocProperties)
.addGap(18)
.addComponent(tableDocStandard, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.UNRELATED)
.addComponent(labelDocCustomProperties, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
.addGap(18)
.addComponent(tableDocCustom, GroupLayout.PREFERRED_SIZE, 322, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, 90, Short.MAX_VALUE)
.addComponent(btnSaveButton)
.addGap(31))
);
}
private void createDocPropsModel() {
Object[][] tableArray = new Object[][] {
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
};
if (docProps != null) {
Object[] arrayOfEntries = docProps.entrySet().toArray();
tableArray = new Object[docProps.size()][2];
for (int i = 0; i < tableArray.length; i++) {
Entry<String, String> entry = (Entry<String, String>) arrayOfEntries[i];
tableArray[i][0] = entry.getKey();
tableArray[i][1] = entry.getValue();
}
}
docPropertiesModel = new DefaultTableModel(
tableArray,
new String[] {
"Metadata name", "Metadata value"
});
}
private MetadataTableModel createOutlineTableModel(OutlineElement element) {
MetadataTableModel outlineTableModel = new MetadataTableModel(element);
return outlineTableModel;
}
private void createCustomDocPropsModel() {
Object[][] tableArray = new Object[][] {
{null, null},
{null, null},
{null, null},
{null, null},
};
if (docCustomProps != null) {
tableArray = new Object[docCustomProps.size()][2];
for (int i = 0; i < tableArray.length; i++) {
CustomDocumentProperty curProp = docCustomProps.get(i);
tableArray[i][0] = curProp.getName();
tableArray[i][1] = curProp.getValue();
}
}
docCustomPropsModel = new DefaultTableModel(
tableArray,
new String[] {
"Metadata name", "Metadata value"
});
}
private static void addPopup(Component component, JPopupMenu popup) {
component.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (e.isPopupTrigger()) {
showMenu(e);
}
}
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
showMenu(e);
}
}
private void showMenu(MouseEvent e) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
});
}
public void saveAction() {
updateDocProps();
document.setDocumentProperties(docProps);
updateDocCustomProps();
document.setCustomDocumentProperties(docCustomProps);
updateOutlineMetadata();
document.writeOutlineMetadata();
document.hideAnnotations();
}
private void updateOutlineMetadata() {
for (MetadataTableModel table : tableModels) {
table.writeToOutline();
}
}
}

View file

@ -0,0 +1,50 @@
package pro.litvinovg.libreoffice.metadata.views;
import java.awt.Component;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.table.TableCellEditor;
public class MetadataCellEditor extends AbstractCellEditor implements TableCellEditor {
JTextArea comp = new JTextArea();
JTable table;
int row;
public MetadataCellEditor() {
comp.setLineWrap(true);
comp.setWrapStyleWord(true);
comp.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
super.componentResized(e);
table.setRowHeight(row, (int) (comp.getPreferredSize().getHeight()));
}
});
comp.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
super.keyTyped(e);
table.setRowHeight(row, (int) (comp.getPreferredSize().getHeight()));
}
});
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
this.table = table;
this.row = row;
comp.setText((String) value);
comp.setFont(table.getFont());
return comp;
}
public Object getCellEditorValue() {
return comp.getText();
}
}

View file

@ -0,0 +1,20 @@
package pro.litvinovg.libreoffice.metadata.views;
import javax.swing.DefaultCellEditor;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class MetadataTable extends JTable {
public TableCellRenderer getCellRenderer(int row, int col) {
return new MetadataTableRenderer();
}
public TableCellEditor getCellEditor(int row, int col) {
return new MetadataCellEditor();
}
}

View file

@ -0,0 +1,35 @@
package pro.litvinovg.libreoffice.metadata.views;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Vector;
import javax.swing.table.DefaultTableModel;
import pro.litvinovg.libreoffice.metadata.CustomDocumentProperty;
import pro.litvinovg.libreoffice.metadata.MetadataElement;
import pro.litvinovg.libreoffice.metadata.OutlineElement;
public class MetadataTableModel extends DefaultTableModel {
private OutlineElement outlineElement;
public MetadataTableModel(OutlineElement element) {
super(element.metadataToArray(), new String[] { "Metadata Name", "Metadata Value" });
this.outlineElement = element;
}
public void writeToOutline() {
Vector dataVector = this.getDataVector();
Enumeration elements = dataVector.elements();
ArrayList<MetadataElement> metadata = new ArrayList<MetadataElement>();
while (elements.hasMoreElements()) {
Vector row = (Vector) elements.nextElement();
String name = (String) row.get(0);
String value = (String) row.get(1);
if (name != null && !name.isEmpty() && value != null && !value.isEmpty()) {
metadata.add(new MetadataElement(name, value));
}
}
outlineElement.setMetadata(metadata);
}
}

View file

@ -0,0 +1,23 @@
package pro.litvinovg.libreoffice.metadata.views;
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.table.TableCellRenderer;
public class MetadataTableRenderer extends JTextArea implements TableCellRenderer{
private static final long serialVersionUID = 1L;
public MetadataTableRenderer() {
setOpaque(true);
setLineWrap(true);
setWrapStyleWord(true);
}
public Component getTableCellRendererComponent(JTable table,Object value,
boolean isSelected, boolean hasFocus, int row,int column) {
this.setText(value == null ? "" : value.toString());
return this;
}
}