diff --git a/.classpath b/.classpath
index 6e6fd97..49276ea 100644
--- a/.classpath
+++ b/.classpath
@@ -3,6 +3,10 @@
-
+
+
+
+
+
diff --git a/.project b/.project
index 605dc2d..98f7e58 100644
--- a/.project
+++ b/.project
@@ -1,6 +1,6 @@
- StarterProject
+ Metadata Editor
diff --git a/.unoproject b/.unoproject
index fa56036..1a2dfbc 100644
--- a/.unoproject
+++ b/.unoproject
@@ -1,10 +1,10 @@
#UNO project configuration file
-#Tue Apr 05 17:37:26 CEST 2016
+#Fri Apr 10 17:20:27 CEST 2020
project.srcdir=/source
-regclassname=org.libreoffice.example.comp.RegistrationHandler
+regclassname=pro.litvinovg.libreoffice.metadata.RegistrationHandler
javaversion=java5
-project.sdk=5.0.5.2
-project.ooo=LibreOffice 5.0
+project.sdk=6.3.5.2
+project.ooo=LibreOffice 6.3 \#1
project.implementation=comp
project.build=build
project.language=Java
diff --git a/README.md b/README.md
index ca44bb9..4475d8c 100644
--- a/README.md
+++ b/README.md
@@ -1,35 +1 @@
-# LibreOffice Starter 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)
+Metadata editor extension
diff --git a/description.xml b/description.xml
index c7b31ab..9a34e6b 100644
--- a/description.xml
+++ b/description.xml
@@ -1,10 +1,20 @@
-
-
+
+
+
+
+
+
+
+
- StarterProject
+ MetadataEditor
+
+
+
+
diff --git a/description/desc_en.txt b/description/desc_en.txt
index c7f5de7..abfb432 100644
--- a/description/desc_en.txt
+++ b/description/desc_en.txt
@@ -1 +1 @@
-LibreOffice Starter Project
+Metadata editor for LibreOffice
diff --git a/dist/StarterProject.oxt b/dist/StarterProject.oxt
deleted file mode 100644
index 1a01ab8..0000000
Binary files a/dist/StarterProject.oxt and /dev/null differ
diff --git a/images/actionOne_16.png b/images/actionOne_16.png
deleted file mode 100644
index fb7409d..0000000
Binary files a/images/actionOne_16.png and /dev/null differ
diff --git a/images/actionOne_26.png b/images/actionOne_26.png
deleted file mode 100644
index 268a528..0000000
Binary files a/images/actionOne_26.png and /dev/null differ
diff --git a/metadataeditor.update.xml b/metadataeditor.update.xml
new file mode 100644
index 0000000..b46d38e
--- /dev/null
+++ b/metadataeditor.update.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/package.properties b/package.properties
index cfffe3d..6463bb9 100644
--- a/package.properties
+++ b/package.properties
@@ -1,3 +1,3 @@
#Written by the OOEclipseIntegration
-#Thu Apr 07 11:36:27 CEST 2016
-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
+#Fri Apr 10 17:15:09 CEST 2020
+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
diff --git a/registry/org/openoffice/Office/Accelerators.xcu b/registry/org/openoffice/Office/Accelerators.xcu
index 07dad35..1374d70 100644
--- a/registry/org/openoffice/Office/Accelerators.xcu
+++ b/registry/org/openoffice/Office/Accelerators.xcu
@@ -7,7 +7,7 @@
- service:org.libreoffice.example.StarterProject?actionOne
+ service:pro.litvinovg.libreoffice.MetadataEditor?openGUI
diff --git a/registry/org/openoffice/Office/Addons.xcu b/registry/org/openoffice/Office/Addons.xcu
index 65cc464..b9d93f3 100644
--- a/registry/org/openoffice/Office/Addons.xcu
+++ b/registry/org/openoffice/Office/Addons.xcu
@@ -1,32 +1,30 @@
-
+
-
+
- service:org.libreoffice.example.StarterProject?actionOne
+ service:pro.litvinovg.libreoffice.MetadataEditor?openGUI
-
- vnd.sun.star.extension://org.libreoffice.example.starterproject/images/actionOne_16.png
-
-
- vnd.sun.star.extension://org.libreoffice.example.starterproject/images/actionOne_26.png
+
+ vnd.sun.star.extension://pro.litvinovg.libreoffice.metadata/images/metadata.png
-
+
Starter Project
+ true
- service:org.libreoffice.example.StarterProject?actionOne
+ service:pro.litvinovg.libreoffice.MetadataEditor?openGUI
_self
@@ -35,35 +33,14 @@
com.sun.star.text.TextDocument
- Action One
+ Open metadata editor GUI
+ Открыть редактор метаданных
-
-
-
- Starter Project
-
-
- com.sun.star.text.TextDocument
-
-
-
-
- Action One
-
-
- service:org.libreoffice.example.StarterProject?actionOne
-
-
- _self
-
-
-
-
-
+
diff --git a/registry/org/openoffice/Office/UI/WriterWindowState.xcu b/registry/org/openoffice/Office/UI/WriterWindowState.xcu
index 3340e7f..a246559 100644
--- a/registry/org/openoffice/Office/UI/WriterWindowState.xcu
+++ b/registry/org/openoffice/Office/UI/WriterWindowState.xcu
@@ -6,9 +6,10 @@
-
+
- Aktensystem
+ Metadata editor
+ Редактор метаданных
10,0
diff --git a/releasenotes.txt b/releasenotes.txt
new file mode 100644
index 0000000..d8a1a26
--- /dev/null
+++ b/releasenotes.txt
@@ -0,0 +1 @@
+0.3.1 Alpha version
diff --git a/source/org/libreoffice/example/comp/RegistrationHandler.classes b/source/org/libreoffice/example/comp/RegistrationHandler.classes
deleted file mode 100644
index c145ca0..0000000
--- a/source/org/libreoffice/example/comp/RegistrationHandler.classes
+++ /dev/null
@@ -1 +0,0 @@
-org.libreoffice.example.comp.StarterProjectImpl
diff --git a/source/org/libreoffice/example/comp/StarterProjectImpl.java b/source/org/libreoffice/example/comp/StarterProjectImpl.java
deleted file mode 100644
index 912c44c..0000000
--- a/source/org/libreoffice/example/comp/StarterProjectImpl.java
+++ /dev/null
@@ -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);
- }
-
- }
-
-}
diff --git a/source/org/libreoffice/example/dialog/ActionOneDialog.java b/source/org/libreoffice/example/dialog/ActionOneDialog.java
deleted file mode 100644
index f3f398f..0000000
--- a/source/org/libreoffice/example/dialog/ActionOneDialog.java
+++ /dev/null
@@ -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;
- }
-
-}
diff --git a/source/org/libreoffice/example/helper/DialogHelper.java b/source/org/libreoffice/example/helper/DialogHelper.java
deleted file mode 100644
index a6df22c..0000000
--- a/source/org/libreoffice/example/helper/DialogHelper.java
+++ /dev/null
@@ -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();
- }
-
-}
diff --git a/source/org/libreoffice/example/helper/DocumentHelper.java b/source/org/libreoffice/example/helper/DocumentHelper.java
deleted file mode 100644
index 4d0be80..0000000
--- a/source/org/libreoffice/example/helper/DocumentHelper.java
+++ /dev/null
@@ -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));
- }
-}
diff --git a/source/org/libreoffice/example/helper/FileHelper.java b/source/org/libreoffice/example/helper/FileHelper.java
deleted file mode 100644
index e9596a2..0000000
--- a/source/org/libreoffice/example/helper/FileHelper.java
+++ /dev/null
@@ -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;
- }
-
-}
diff --git a/source/pro/litvinovg/libreoffice/DocumentParser.java b/source/pro/litvinovg/libreoffice/DocumentParser.java
new file mode 100644
index 0000000..91b227f
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/DocumentParser.java
@@ -0,0 +1,6 @@
+package pro.litvinovg.libreoffice;
+
+public interface DocumentParser {
+
+ public void parse();
+}
diff --git a/source/pro/litvinovg/libreoffice/DocumentParserImpl.java b/source/pro/litvinovg/libreoffice/DocumentParserImpl.java
new file mode 100644
index 0000000..7c1131f
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/DocumentParserImpl.java
@@ -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);
+ }
+}
diff --git a/source/pro/litvinovg/libreoffice/MetadataCleaner.java b/source/pro/litvinovg/libreoffice/MetadataCleaner.java
new file mode 100644
index 0000000..3b0e28c
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/MetadataCleaner.java
@@ -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();
+ }
+ }
+}
diff --git a/source/pro/litvinovg/libreoffice/MetadataReader.java b/source/pro/litvinovg/libreoffice/MetadataReader.java
new file mode 100644
index 0000000..cbc6d2e
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/MetadataReader.java
@@ -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 outline;
+ private boolean firstPara = true;
+
+ public MetadataReader(XText text, ArrayList 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()));
+ }
+ }
+ }
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/CustomDocumentProperty.java b/source/pro/litvinovg/libreoffice/metadata/CustomDocumentProperty.java
new file mode 100644
index 0000000..b2efd3b
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/CustomDocumentProperty.java
@@ -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;
+ }
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java
new file mode 100644
index 0000000..9d920a7
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/Document.java
@@ -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 outline = new ArrayList();
+ 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 docCustomProps) {
+ documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
+ documentProperties = documentPropertiesSupplier.getDocumentProperties();
+ removeStringProperties();
+ addStringProperties(docCustomProps);
+ }
+
+ private void addStringProperties(ArrayList 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 getDocumentCustomProperties() {
+ ArrayList customProps = new ArrayList();
+ 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() {
+ 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 getDocumentProperties() {
+ documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
+ documentProperties = documentPropertiesSupplier.getDocumentProperties();
+ Map docProps = new HashMap();
+ 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 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() {
+ 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 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(); }
+ */
+
+ }
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java
new file mode 100644
index 0000000..55d5c26
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java
@@ -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;
+ }
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java b/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java
new file mode 100644
index 0000000..5bc37f7
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java
@@ -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 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;
+}
+
+
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataExtensionImpl.java b/source/pro/litvinovg/libreoffice/metadata/MetadataExtensionImpl.java
new file mode 100644
index 0000000..b3a8c75
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/MetadataExtensionImpl.java
@@ -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:
+ }
+
+ }
+
+
+
+
+
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataInaccessableException.java b/source/pro/litvinovg/libreoffice/metadata/MetadataInaccessableException.java
new file mode 100644
index 0000000..b4236bb
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/MetadataInaccessableException.java
@@ -0,0 +1,7 @@
+package pro.litvinovg.libreoffice.metadata;
+
+public class MetadataInaccessableException extends Exception {
+ public MetadataInaccessableException(String errorMessage) {
+ super(errorMessage);
+ }
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java
new file mode 100644
index 0000000..a29b722
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java
@@ -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 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();
+ }
+
+ 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 nums = json.keySet();
+ for (String number : nums) {
+ JSONObject meta = (JSONObject) json.get(number);
+ Set 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 metadataInput) {
+ this.metadata.clear();
+ this.metadata.addAll(metadataInput);
+}
+
+
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/RegistrationHandler.classes b/source/pro/litvinovg/libreoffice/metadata/RegistrationHandler.classes
new file mode 100644
index 0000000..11d576c
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/RegistrationHandler.classes
@@ -0,0 +1 @@
+pro.litvinovg.libreoffice.metadata.MetadataExtensionImpl
diff --git a/source/org/libreoffice/example/comp/RegistrationHandler.java b/source/pro/litvinovg/libreoffice/metadata/RegistrationHandler.java
similarity index 99%
rename from source/org/libreoffice/example/comp/RegistrationHandler.java
rename to source/pro/litvinovg/libreoffice/metadata/RegistrationHandler.java
index 3819b73..a67e63e 100644
--- a/source/org/libreoffice/example/comp/RegistrationHandler.java
+++ b/source/pro/litvinovg/libreoffice/metadata/RegistrationHandler.java
@@ -35,7 +35,7 @@
*
*
************************************************************************/
-package org.libreoffice.example.comp;
+package pro.litvinovg.libreoffice.metadata;
import java.io.IOException;
import java.io.InputStream;
diff --git a/source/pro/litvinovg/libreoffice/metadata/resources/metadata.png b/source/pro/litvinovg/libreoffice/metadata/resources/metadata.png
new file mode 100644
index 0000000..a7af7ee
Binary files /dev/null and b/source/pro/litvinovg/libreoffice/metadata/resources/metadata.png differ
diff --git a/source/pro/litvinovg/libreoffice/metadata/tests/UnoTests.java b/source/pro/litvinovg/libreoffice/metadata/tests/UnoTests.java
new file mode 100644
index 0000000..197cf39
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/tests/UnoTests.java
@@ -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 {
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/tests/base/UnoSuite.java b/source/pro/litvinovg/libreoffice/metadata/tests/base/UnoSuite.java
new file mode 100644
index 0000000..96f31f6
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/tests/base/UnoSuite.java
@@ -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 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;
+ }
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/tests/helper/UnoHelper.java b/source/pro/litvinovg/libreoffice/metadata/tests/helper/UnoHelper.java
new file mode 100644
index 0000000..b639762
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/tests/helper/UnoHelper.java
@@ -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);
+ }
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/tests/uno/WriterTest.java b/source/pro/litvinovg/libreoffice/metadata/tests/uno/WriterTest.java
new file mode 100644
index 0000000..752bba8
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/tests/uno/WriterTest.java
@@ -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);
+ }
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java
new file mode 100644
index 0000000..4de8c9e
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java
@@ -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 tableModels ;
+
+ //Component models
+ private DefaultTableModel docPropertiesModel;
+ private DefaultTableModel docCustomPropsModel;
+
+
+ private static JFrame singleFrame = null;
+
+
+ private Map docProps;
+ private ArrayList docCustomProps;
+ private Document document = null;
+ private JButton btnSaveButton;
+ private JMenuItem menuItemPupupDocUserProps;
+ private ArrayList 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();
+ initComponents();
+ createEvents();
+ }
+
+ public EditorGUI() {
+ outline = new ArrayList();
+ 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 entry = (Entry) 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();
+ }
+ }
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/views/MetadataCellEditor.java b/source/pro/litvinovg/libreoffice/metadata/views/MetadataCellEditor.java
new file mode 100644
index 0000000..bc1fe6a
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/views/MetadataCellEditor.java
@@ -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();
+ }
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/views/MetadataTable.java b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTable.java
new file mode 100644
index 0000000..63ea8ad
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTable.java
@@ -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();
+ }
+
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableModel.java b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableModel.java
new file mode 100644
index 0000000..124ae13
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableModel.java
@@ -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 metadata = new ArrayList();
+ 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);
+ }
+}
diff --git a/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableRenderer.java b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableRenderer.java
new file mode 100644
index 0000000..cde3583
--- /dev/null
+++ b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableRenderer.java
@@ -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;
+ }
+}