From f9a9aefc7227f96aad95f048bb4c35480f151754 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Tue, 7 Apr 2020 18:09:17 +0200 Subject: [PATCH 01/31] GUI working --- .../example/comp/StarterProjectImpl.java | 50 +++- .../metadata/CustomDocumentProperty.java | 21 ++ .../libreoffice/metadata/Document.java | 180 ++++++++++++ .../metadata/resources/clock128.gif | Bin 0 -> 7713 bytes .../libreoffice/metadata/resources/cura.png | Bin 0 -> 10802 bytes .../metadata/resources/eclipse.png | Bin 0 -> 14781 bytes .../libreoffice/metadata/resources/webcam.png | Bin 0 -> 30877 bytes .../libreoffice/metadata/views/EditorGUI.java | 273 ++++++++++++++++++ 8 files changed, 514 insertions(+), 10 deletions(-) create mode 100644 source/pro/litvinovg/libreoffice/metadata/CustomDocumentProperty.java create mode 100644 source/pro/litvinovg/libreoffice/metadata/Document.java create mode 100644 source/pro/litvinovg/libreoffice/metadata/resources/clock128.gif create mode 100644 source/pro/litvinovg/libreoffice/metadata/resources/cura.png create mode 100644 source/pro/litvinovg/libreoffice/metadata/resources/eclipse.png create mode 100644 source/pro/litvinovg/libreoffice/metadata/resources/webcam.png create mode 100644 source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java diff --git a/source/org/libreoffice/example/comp/StarterProjectImpl.java b/source/org/libreoffice/example/comp/StarterProjectImpl.java index 912c44c..de058c8 100644 --- a/source/org/libreoffice/example/comp/StarterProjectImpl.java +++ b/source/org/libreoffice/example/comp/StarterProjectImpl.java @@ -1,11 +1,29 @@ package org.libreoffice.example.comp; +import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; + +import pro.litvinovg.libreoffice.metadata.Document; +import pro.litvinovg.libreoffice.metadata.views.EditorGUI; + import com.sun.star.lib.uno.helper.Factory; +import java.util.Arrays; +import java.util.Comparator; + import org.libreoffice.example.dialog.ActionOneDialog; import org.libreoffice.example.helper.DialogHelper; +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; @@ -15,16 +33,20 @@ public final class StarterProjectImpl extends WeakBase implements com.sun.star.lang.XServiceInfo, com.sun.star.task.XJobExecutor { - private final XComponentContext m_xContext; + 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 = StarterProjectImpl.class.getName(); - private static final String[] m_serviceNames = { - "org.libreoffice.example.StarterProject" }; + private static final String[] m_serviceNames = { "org.libreoffice.example.StarterProject" }; - public StarterProjectImpl( XComponentContext context ) - { - m_xContext = context; - }; + public StarterProjectImpl(XComponentContext componentContext) { + context = componentContext; + + }; public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) { XSingleComponentFactory xFactory = null; @@ -64,13 +86,21 @@ public final class StarterProjectImpl extends WeakBase { switch (action) { case "actionOne": - ActionOneDialog actionOneDialog = new ActionOneDialog(m_xContext); - actionOneDialog.show(); + //ActionOneDialog actionOneDialog = new ActionOneDialog(m_xContext); + //actionOneDialog.show(); + + Document doc = new Document(context); + EditorGUI.runGUI(doc); break; default: - DialogHelper.showErrorMessage(m_xContext, null, "Unknown action: " + action); + DialogHelper.showErrorMessage(context, null, "Unknown action: " + action); } } + + + + + } 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..ab9cc25 --- /dev/null +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -0,0 +1,180 @@ +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 org.libreoffice.example.comp.MetadataInaccessableException; + +import com.sun.org.apache.bcel.internal.generic.NEW; +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.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; + +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 XComponentContext context; + private XDesktop xDesktop; + private XMultiComponentFactory multiComponentFactory; + private XComponent currentDocument; + private XDocumentProperties documentProperties; + private XDocumentPropertiesSupplier documentPropertiesSupplier; + + 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(); + } catch (Exception e) { + System.out.println("xDesktop inaccessible. Can not proceed."); + e.printStackTrace(); + System.exit(1); + } + logProperties(); + } + + 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 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)); + System.out.println("set author" + 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 updateDocProperty(String propertyName, Map docProps) { + + } + + 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; + } +} diff --git a/source/pro/litvinovg/libreoffice/metadata/resources/clock128.gif b/source/pro/litvinovg/libreoffice/metadata/resources/clock128.gif new file mode 100644 index 0000000000000000000000000000000000000000..73d35051ab1d3dddf01d594f196133d8c3bd6492 GIT binary patch literal 7713 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 OF-Z38`du0TZ2LcWxBlt? literal 0 HcmV?d00001 diff --git a/source/pro/litvinovg/libreoffice/metadata/resources/cura.png b/source/pro/litvinovg/libreoffice/metadata/resources/cura.png new file mode 100644 index 0000000000000000000000000000000000000000..c311b868ee70bf3007682dcf3c3f7314e78e45f3 GIT binary patch literal 10802 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 OlY#DqbA@N@LjDgw+L_G& literal 0 HcmV?d00001 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..5e807c4 --- /dev/null +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -0,0 +1,273 @@ +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 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; + +public class EditorGUI extends JFrame { + //Components + private JTable tableDocProps; + private JTable tableDocCustomProps; + + + //Component models + private DefaultTableModel docPropertiesModel; + private DefaultTableModel docCustomPropsModel; + + + private Map docProps; + private ArrayList docCustomProps; + private Document document = null; + private JButton btnNewButton; + + + /** + * Launch the application. + */ + public static void main(String[] args) { + testGUI(); + } + + public static void runGUI(Document doc) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Throwable e) { + e.printStackTrace(); + } + EventQueue.invokeLater(new Runnable() { + public void run() { + try { + EditorGUI frame = new EditorGUI(doc); + 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.setVisible(true); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + public EditorGUI(Document doc) { + this.document = doc; + docProps = document.getDocumentProperties(); + docCustomProps = document.getDocumentCustomProperties(); + initComponents(); + createEvents(); + } + + public EditorGUI() { + initComponents(); + createEvents(); + } + + private void createEvents() { + btnNewButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateDocProps(); + document.setDocumentProperties(docProps); + } + }); + } + private void updateDocProps() { + System.out.println("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() { + setIconImage(Toolkit.getDefaultToolkit().getImage(EditorGUI.class.getResource("/pro/litvinovg/libreoffice/metadata/resources/webcam.png"))); + setTitle("Редактор метаданных"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setBounds(100, 100, 1064, 733); + getContentPane().setLayout(null); + getContentPane().setLayout(new GridLayout(0, 1, 0, 0)); + + JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.LEFT, JTabbedPane.SCROLL_TAB_LAYOUT); + tabbedPane.setBounds(125, 138, 913, 546); + getContentPane().add(tabbedPane); + + JPanel panel = new JPanel(); + tabbedPane.addTab("Документ", null, panel, null); + tabbedPane.setEnabledAt(0, true); + + + createDocPropsModel(); + createCustomDocPropsModel(); + + + tableDocProps = new JTable(); + tableDocProps.setCellSelectionEnabled(true); + tableDocProps.setFillsViewportHeight(true); + tableDocProps.setModel(docPropertiesModel); + + tableDocCustomProps = new JTable(); + tableDocCustomProps.setFillsViewportHeight(true); + tableDocCustomProps.setCellSelectionEnabled(true); + tableDocCustomProps.setModel(docCustomPropsModel); + + btnNewButton = new JButton("Save"); + + GroupLayout gl_panel = new GroupLayout(panel); + gl_panel.setHorizontalGroup( + gl_panel.createParallelGroup(Alignment.TRAILING) + .addGroup(Alignment.LEADING, gl_panel.createSequentialGroup() + .addContainerGap() + .addGroup(gl_panel.createParallelGroup(Alignment.LEADING) + .addGroup(gl_panel.createSequentialGroup() + .addComponent(tableDocProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(Alignment.TRAILING, gl_panel.createSequentialGroup() + .addComponent(btnNewButton) + .addGap(58)) + .addGroup(Alignment.TRAILING, gl_panel.createSequentialGroup() + .addComponent(tableDocCustomProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) + .addContainerGap()))) + ); + gl_panel.setVerticalGroup( + gl_panel.createParallelGroup(Alignment.LEADING) + .addGroup(gl_panel.createSequentialGroup() + .addGap(86) + .addComponent(tableDocProps, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addGap(18) + .addComponent(tableDocCustomProps, GroupLayout.DEFAULT_SIZE, 368, Short.MAX_VALUE) + .addGap(75) + .addComponent(btnNewButton) + .addGap(27)) + ); + panel.setLayout(gl_panel); + + + JMenuBar menuBar = new JMenuBar(); + setJMenuBar(menuBar); + + JMenu mnFile = new JMenu("Файл"); + menuBar.add(mnFile); + + JMenu mnEdit = new JMenu("Edit"); + menuBar.add(mnEdit); + } + + 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 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, final 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()); + } + }); + } +} From 425bd82592da927e40edc40b3ba474d10ad816af Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Wed, 8 Apr 2020 13:42:49 +0200 Subject: [PATCH 02/31] Works for document properties. --- .../comp/MetadataInaccessableException.java | 7 ++ .../libreoffice/metadata/Document.java | 71 +++++++++++++++++-- .../libreoffice/metadata/views/EditorGUI.java | 70 ++++++++++++++---- 3 files changed, 126 insertions(+), 22 deletions(-) create mode 100644 source/org/libreoffice/example/comp/MetadataInaccessableException.java diff --git a/source/org/libreoffice/example/comp/MetadataInaccessableException.java b/source/org/libreoffice/example/comp/MetadataInaccessableException.java new file mode 100644 index 0000000..da1ccb2 --- /dev/null +++ b/source/org/libreoffice/example/comp/MetadataInaccessableException.java @@ -0,0 +1,7 @@ +package org.libreoffice.example.comp; + +public class MetadataInaccessableException extends Exception { + public MetadataInaccessableException(String errorMessage) { + super(errorMessage); + } +} diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index ab9cc25..178c9ce 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -1,5 +1,6 @@ package pro.litvinovg.libreoffice.metadata; +import java.nio.file.attribute.UserDefinedFileAttributeView; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -8,13 +9,18 @@ import java.util.Map; import org.libreoffice.example.comp.MetadataInaccessableException; import com.sun.org.apache.bcel.internal.generic.NEW; +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.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.XDesktop; +import com.sun.star.lang.IllegalArgumentException; import com.sun.star.lang.XComponent; import com.sun.star.lang.XMultiComponentFactory; import com.sun.star.uno.UnoRuntime; @@ -27,7 +33,7 @@ public class Document { 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; private XComponentContext context; private XDesktop xDesktop; @@ -48,7 +54,7 @@ public class Document { e.printStackTrace(); System.exit(1); } - logProperties(); + //logProperties(); } private void getCurrentDocument() throws MetadataInaccessableException { @@ -62,7 +68,61 @@ public class Document { 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); @@ -116,7 +176,6 @@ public class Document { documentProperties = documentPropertiesSupplier.getDocumentProperties(); if (docProps.containsKey(DOC_AUTHOR)) { documentProperties.setAuthor(docProps.get(DOC_AUTHOR)); - System.out.println("set author" + docProps.get(DOC_AUTHOR)); } if (docProps.containsKey(DOC_TITLE)) { documentProperties.setTitle(docProps.get(DOC_TITLE)); @@ -132,10 +191,6 @@ public class Document { } } - private void updateDocProperty(String propertyName, Map docProps) { - - } - private void logDocumentProperties() { documentPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument); documentProperties = documentPropertiesSupplier.getDocumentProperties(); @@ -177,4 +232,6 @@ public class Document { } return value; } + + } diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index 5e807c4..9ab7fd6 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -40,6 +40,10 @@ 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; public class EditorGUI extends JFrame { //Components @@ -56,6 +60,7 @@ public class EditorGUI extends JFrame { private ArrayList docCustomProps; private Document document = null; private JButton btnNewButton; + private JMenuItem menuItemPupupDocUserProps; /** @@ -75,6 +80,7 @@ public class EditorGUI extends JFrame { public void run() { try { EditorGUI frame = new EditorGUI(doc); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); @@ -93,6 +99,7 @@ public class EditorGUI extends JFrame { public void run() { try { EditorGUI frame = new EditorGUI(); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); @@ -118,11 +125,32 @@ public class EditorGUI extends JFrame { public void actionPerformed(ActionEvent e) { updateDocProps(); document.setDocumentProperties(docProps); + updateDocCustomProps(); + document.setCustomDocumentProperties(docCustomProps); + } + }); + + 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() { - System.out.println("updateDocProps"); Vector dataVector = docPropertiesModel.getDataVector(); Enumeration elements = dataVector.elements(); docProps.clear(); @@ -155,11 +183,16 @@ public class EditorGUI extends JFrame { tableDocProps = new JTable(); + tableDocProps.putClientProperty("terminateEditOnFocusLost", true); + tableDocProps.setSurrendersFocusOnKeystroke(true); tableDocProps.setCellSelectionEnabled(true); tableDocProps.setFillsViewportHeight(true); tableDocProps.setModel(docPropertiesModel); tableDocCustomProps = new JTable(); + tableDocCustomProps.putClientProperty("terminateEditOnFocusLost", true); + + tableDocCustomProps.setSurrendersFocusOnKeystroke(true); tableDocCustomProps.setFillsViewportHeight(true); tableDocCustomProps.setCellSelectionEnabled(true); tableDocCustomProps.setModel(docCustomPropsModel); @@ -168,31 +201,38 @@ public class EditorGUI extends JFrame { GroupLayout gl_panel = new GroupLayout(panel); gl_panel.setHorizontalGroup( - gl_panel.createParallelGroup(Alignment.TRAILING) - .addGroup(Alignment.LEADING, gl_panel.createSequentialGroup() + gl_panel.createParallelGroup(Alignment.LEADING) + .addGroup(Alignment.TRAILING, gl_panel.createSequentialGroup() + .addContainerGap(838, Short.MAX_VALUE) + .addComponent(btnNewButton) + .addGap(58)) + .addGroup(gl_panel.createSequentialGroup() .addContainerGap() - .addGroup(gl_panel.createParallelGroup(Alignment.LEADING) - .addGroup(gl_panel.createSequentialGroup() - .addComponent(tableDocProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) - .addContainerGap()) - .addGroup(Alignment.TRAILING, gl_panel.createSequentialGroup() - .addComponent(btnNewButton) - .addGap(58)) - .addGroup(Alignment.TRAILING, gl_panel.createSequentialGroup() - .addComponent(tableDocCustomProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) - .addContainerGap()))) + .addComponent(tableDocCustomProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(gl_panel.createSequentialGroup() + .addContainerGap() + .addComponent(tableDocProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) + .addContainerGap()) ); gl_panel.setVerticalGroup( gl_panel.createParallelGroup(Alignment.LEADING) .addGroup(gl_panel.createSequentialGroup() .addGap(86) .addComponent(tableDocProps, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) - .addGap(18) + .addPreferredGap(ComponentPlacement.UNRELATED) .addComponent(tableDocCustomProps, GroupLayout.DEFAULT_SIZE, 368, Short.MAX_VALUE) - .addGap(75) + .addGap(81) .addComponent(btnNewButton) .addGap(27)) ); + + JPopupMenu popupMenu = new JPopupMenu(); + addPopup(tableDocCustomProps, popupMenu); + + menuItemPupupDocUserProps = new JMenuItem("Добавить строку"); + + popupMenu.add(menuItemPupupDocUserProps); panel.setLayout(gl_panel); From 79c0051ee5c747af4537850e7e1e1ee052d5b57f Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Wed, 8 Apr 2020 16:43:04 +0200 Subject: [PATCH 03/31] Removed menu --- registry/org/openoffice/Office/Addons.xcu | 28 ++----------------- .../example/comp/StarterProjectImpl.java | 5 +--- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/registry/org/openoffice/Office/Addons.xcu b/registry/org/openoffice/Office/Addons.xcu index 65cc464..6726259 100644 --- a/registry/org/openoffice/Office/Addons.xcu +++ b/registry/org/openoffice/Office/Addons.xcu @@ -6,7 +6,7 @@ - service:org.libreoffice.example.StarterProject?actionOne + service:org.libreoffice.example.StarterProject?openGUI @@ -26,7 +26,7 @@ - service:org.libreoffice.example.StarterProject?actionOne + service:org.libreoffice.example.StarterProject?openGUI _self @@ -41,29 +41,7 @@ - - - - Starter Project - - - com.sun.star.text.TextDocument - - - - - Action One - - - service:org.libreoffice.example.StarterProject?actionOne - - - _self - - - - - + diff --git a/source/org/libreoffice/example/comp/StarterProjectImpl.java b/source/org/libreoffice/example/comp/StarterProjectImpl.java index de058c8..e6320ef 100644 --- a/source/org/libreoffice/example/comp/StarterProjectImpl.java +++ b/source/org/libreoffice/example/comp/StarterProjectImpl.java @@ -85,10 +85,7 @@ public final class StarterProjectImpl extends WeakBase public void trigger(String action) { switch (action) { - case "actionOne": - //ActionOneDialog actionOneDialog = new ActionOneDialog(m_xContext); - //actionOneDialog.show(); - + case "openGUI": Document doc = new Document(context); EditorGUI.runGUI(doc); break; From 620425f43d63449d68123b569ae1bb27898e6a2c Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Wed, 8 Apr 2020 17:15:57 +0200 Subject: [PATCH 04/31] Renamings --- .unoproject | 8 +- dialog/ActionOneDialog.xdl | 12 -- .../org/openoffice/Office/Accelerators.xcu | 2 +- registry/org/openoffice/Office/Addons.xcu | 12 +- .../Office/UI/WriterWindowState.xcu | 2 +- .../example/comp/RegistrationHandler.classes | 1 - .../example/dialog/ActionOneDialog.java | 43 ---- .../example/helper/DialogHelper.java | 184 ------------------ .../example/helper/DocumentHelper.java | 42 ---- .../example/helper/FileHelper.java | 59 ------ .../libreoffice/metadata/Document.java | 1 - .../metadata/MetadataExtensionImpl.java} | 17 +- .../MetadataInaccessableException.java | 2 +- .../metadata/RegistrationHandler.classes | 1 + .../metadata}/RegistrationHandler.java | 2 +- .../libreoffice/metadata/tests/UnoTests.java | 13 ++ .../metadata/tests/base/UnoSuite.java | 75 +++++++ .../metadata/tests/helper/UnoHelper.java | 28 +++ .../metadata/tests/uno/WriterTest.java | 26 +++ 19 files changed, 163 insertions(+), 367 deletions(-) delete mode 100644 dialog/ActionOneDialog.xdl delete mode 100644 source/org/libreoffice/example/comp/RegistrationHandler.classes delete mode 100644 source/org/libreoffice/example/dialog/ActionOneDialog.java delete mode 100644 source/org/libreoffice/example/helper/DialogHelper.java delete mode 100644 source/org/libreoffice/example/helper/DocumentHelper.java delete mode 100644 source/org/libreoffice/example/helper/FileHelper.java rename source/{org/libreoffice/example/comp/StarterProjectImpl.java => pro/litvinovg/libreoffice/metadata/MetadataExtensionImpl.java} (78%) rename source/{org/libreoffice/example/comp => pro/litvinovg/libreoffice/metadata}/MetadataInaccessableException.java (77%) create mode 100644 source/pro/litvinovg/libreoffice/metadata/RegistrationHandler.classes rename source/{org/libreoffice/example/comp => pro/litvinovg/libreoffice/metadata}/RegistrationHandler.java (99%) create mode 100644 source/pro/litvinovg/libreoffice/metadata/tests/UnoTests.java create mode 100644 source/pro/litvinovg/libreoffice/metadata/tests/base/UnoSuite.java create mode 100644 source/pro/litvinovg/libreoffice/metadata/tests/helper/UnoHelper.java create mode 100644 source/pro/litvinovg/libreoffice/metadata/tests/uno/WriterTest.java diff --git a/.unoproject b/.unoproject index fa56036..67bde5b 100644 --- a/.unoproject +++ b/.unoproject @@ -1,10 +1,10 @@ #UNO project configuration file -#Tue Apr 05 17:37:26 CEST 2016 +#Thu Mar 19 15:58:57 CET 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/dialog/ActionOneDialog.xdl b/dialog/ActionOneDialog.xdl deleted file mode 100644 index 8bf5705..0000000 --- a/dialog/ActionOneDialog.xdl +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file 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 6726259..ed333cb 100644 --- a/registry/org/openoffice/Office/Addons.xcu +++ b/registry/org/openoffice/Office/Addons.xcu @@ -4,29 +4,29 @@ - + - service:org.libreoffice.example.StarterProject?openGUI + service:pro.litvinovg.libreoffice.MetadataEditor?openGUI - vnd.sun.star.extension://org.libreoffice.example.starterproject/images/actionOne_16.png + vnd.sun.star.extension://pro.litvinovg.libreoffice.metadata/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/actionOne_26.png - + Starter Project - service:org.libreoffice.example.StarterProject?openGUI + service:pro.litvinovg.libreoffice.MetadataEditor?openGUI _self diff --git a/registry/org/openoffice/Office/UI/WriterWindowState.xcu b/registry/org/openoffice/Office/UI/WriterWindowState.xcu index 3340e7f..4c6a311 100644 --- a/registry/org/openoffice/Office/UI/WriterWindowState.xcu +++ b/registry/org/openoffice/Office/UI/WriterWindowState.xcu @@ -6,7 +6,7 @@ - + Aktensystem 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/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/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index 178c9ce..e9c69f8 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -6,7 +6,6 @@ import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.Map; -import org.libreoffice.example.comp.MetadataInaccessableException; import com.sun.org.apache.bcel.internal.generic.NEW; import com.sun.star.beans.IllegalTypeException; diff --git a/source/org/libreoffice/example/comp/StarterProjectImpl.java b/source/pro/litvinovg/libreoffice/metadata/MetadataExtensionImpl.java similarity index 78% rename from source/org/libreoffice/example/comp/StarterProjectImpl.java rename to source/pro/litvinovg/libreoffice/metadata/MetadataExtensionImpl.java index e6320ef..b3a8c75 100644 --- a/source/org/libreoffice/example/comp/StarterProjectImpl.java +++ b/source/pro/litvinovg/libreoffice/metadata/MetadataExtensionImpl.java @@ -1,9 +1,8 @@ -package org.libreoffice.example.comp; +package pro.litvinovg.libreoffice.metadata; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; -import pro.litvinovg.libreoffice.metadata.Document; import pro.litvinovg.libreoffice.metadata.views.EditorGUI; import com.sun.star.lib.uno.helper.Factory; @@ -11,9 +10,6 @@ import com.sun.star.lib.uno.helper.Factory; import java.util.Arrays; import java.util.Comparator; -import org.libreoffice.example.dialog.ActionOneDialog; -import org.libreoffice.example.helper.DialogHelper; - import com.sun.star.beans.Property; import com.sun.star.beans.XPropertyContainer; import com.sun.star.beans.XPropertySet; @@ -29,7 +25,7 @@ import com.sun.star.registry.XRegistryKey; import com.sun.star.lib.uno.helper.WeakBase; -public final class StarterProjectImpl extends WeakBase +public final class MetadataExtensionImpl extends WeakBase implements com.sun.star.lang.XServiceInfo, com.sun.star.task.XJobExecutor { @@ -39,11 +35,11 @@ public final class StarterProjectImpl extends WeakBase private XComponent currentDocument; private XDocumentProperties documentProperties; private XDocumentPropertiesSupplier documentPropertiesSupplier; - private static final String m_implementationName = StarterProjectImpl.class.getName(); - private static final String[] m_serviceNames = { "org.libreoffice.example.StarterProject" }; + private static final String m_implementationName = MetadataExtensionImpl.class.getName(); + private static final String[] m_serviceNames = { "pro.litvinovg.libreoffice.MetadataEditor" }; - public StarterProjectImpl(XComponentContext componentContext) { + public MetadataExtensionImpl(XComponentContext componentContext) { context = componentContext; }; @@ -52,7 +48,7 @@ public final class StarterProjectImpl extends WeakBase XSingleComponentFactory xFactory = null; if ( sImplementationName.equals( m_implementationName ) ) - xFactory = Factory.createComponentFactory(StarterProjectImpl.class, m_serviceNames); + xFactory = Factory.createComponentFactory(MetadataExtensionImpl.class, m_serviceNames); return xFactory; } @@ -90,7 +86,6 @@ public final class StarterProjectImpl extends WeakBase EditorGUI.runGUI(doc); break; default: - DialogHelper.showErrorMessage(context, null, "Unknown action: " + action); } } diff --git a/source/org/libreoffice/example/comp/MetadataInaccessableException.java b/source/pro/litvinovg/libreoffice/metadata/MetadataInaccessableException.java similarity index 77% rename from source/org/libreoffice/example/comp/MetadataInaccessableException.java rename to source/pro/litvinovg/libreoffice/metadata/MetadataInaccessableException.java index da1ccb2..b4236bb 100644 --- a/source/org/libreoffice/example/comp/MetadataInaccessableException.java +++ b/source/pro/litvinovg/libreoffice/metadata/MetadataInaccessableException.java @@ -1,4 +1,4 @@ -package org.libreoffice.example.comp; +package pro.litvinovg.libreoffice.metadata; public class MetadataInaccessableException extends Exception { public MetadataInaccessableException(String errorMessage) { 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/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); + } + +} From be4279323e47cc2aab7495201436b79dd4e0e4c0 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Wed, 8 Apr 2020 17:30:25 +0200 Subject: [PATCH 05/31] Reverted dialog removal --- description.xml | 6 +++--- dialog/ActionOneDialog.xdl | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 dialog/ActionOneDialog.xdl diff --git a/description.xml b/description.xml index c7b31ab..f22fb48 100644 --- a/description.xml +++ b/description.xml @@ -1,9 +1,9 @@ - - + + - StarterProject + MetadataEditor diff --git a/dialog/ActionOneDialog.xdl b/dialog/ActionOneDialog.xdl new file mode 100644 index 0000000..8bf5705 --- /dev/null +++ b/dialog/ActionOneDialog.xdl @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file From c37b01eb929f3dde41d3f3dedbe0a10bff61e76e Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Wed, 8 Apr 2020 17:42:48 +0200 Subject: [PATCH 06/31] Added some translations --- README.md | 36 +------------------ description/desc_en.txt | 2 +- package.properties | 2 +- registry/org/openoffice/Office/Addons.xcu | 6 ++-- .../Office/UI/WriterWindowState.xcu | 3 +- 5 files changed, 9 insertions(+), 40 deletions(-) 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/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/package.properties b/package.properties index cfffe3d..e081b50 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 +contents=description, description/desc_en.txt, 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 diff --git a/registry/org/openoffice/Office/Addons.xcu b/registry/org/openoffice/Office/Addons.xcu index ed333cb..ebf48dc 100644 --- a/registry/org/openoffice/Office/Addons.xcu +++ b/registry/org/openoffice/Office/Addons.xcu @@ -20,10 +20,11 @@ - + Starter Project + true service:pro.litvinovg.libreoffice.MetadataEditor?openGUI @@ -35,7 +36,8 @@ com.sun.star.text.TextDocument - Action One + Open metadata editor GUI + Открыть редактор метаданных diff --git a/registry/org/openoffice/Office/UI/WriterWindowState.xcu b/registry/org/openoffice/Office/UI/WriterWindowState.xcu index 4c6a311..a246559 100644 --- a/registry/org/openoffice/Office/UI/WriterWindowState.xcu +++ b/registry/org/openoffice/Office/UI/WriterWindowState.xcu @@ -8,7 +8,8 @@ - Aktensystem + Metadata editor + Редактор метаданных 10,0 From 71776fa54beea0c582cfbf0d2003bcd66834cda2 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 9 Apr 2020 15:03:47 +0200 Subject: [PATCH 07/31] Working on outline metadata --- .../libreoffice/metadata/Document.java | 65 +++++++++++++++ .../libreoffice/metadata/MetadataElement.java | 43 ++++++++++ .../libreoffice/metadata/OutlineElement.java | 79 +++++++++++++++++++ .../libreoffice/metadata/views/EditorGUI.java | 50 ++++++++---- 4 files changed, 220 insertions(+), 17 deletions(-) create mode 100644 source/pro/litvinovg/libreoffice/metadata/MetadataElement.java create mode 100644 source/pro/litvinovg/libreoffice/metadata/OutlineElement.java diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index e9c69f8..ce57393 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -16,12 +16,21 @@ 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.container.NoSuchElementException; +import com.sun.star.container.XEnumeration; +import com.sun.star.container.XEnumerationAccess; import com.sun.star.document.XDocumentProperties; import com.sun.star.document.XDocumentPropertiesSupplier; import com.sun.star.frame.XDesktop; 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.XServiceInfo; +import com.sun.star.text.XText; +import com.sun.star.text.XTextContent; +import com.sun.star.text.XTextDocument; +import com.sun.star.text.XTextRange; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; @@ -40,6 +49,7 @@ public class Document { private XComponent currentDocument; private XDocumentProperties documentProperties; private XDocumentPropertiesSupplier documentPropertiesSupplier; + private XText text = null; public Document(XComponentContext componentContext) { context = componentContext; @@ -48,6 +58,8 @@ public class Document { Object oDesktop = multiComponentFactory.createInstanceWithContext("com.sun.star.frame.Desktop", context); xDesktop = UnoRuntime.queryInterface(XDesktop.class, oDesktop); getCurrentDocument(); + getDocumentText(); + updateChapterMetadata(); } catch (Exception e) { System.out.println("xDesktop inaccessible. Can not proceed."); e.printStackTrace(); @@ -56,6 +68,51 @@ public class Document { //logProperties(); } + private void getDocumentText() { + XTextDocument textDocument = UnoRuntime.queryInterface(XTextDocument.class,currentDocument); + text = textDocument.getText(); + } + + private void updateChapterMetadata() { + findAllChapters(); + } + + private void findAllChapters() { + XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, text); + XEnumeration textEnum = enumAccess.createEnumeration(); + while (textEnum.hasMoreElements()) { + try { + XTextContent textContent = UnoRuntime.queryInterface(XTextContent.class, textEnum.nextElement()); + if(isSupported(textContent, "com.sun.star.text.TextTable")) { + //TODO: Go over table to check for outline elements + } else + if (isSupported(textContent, "com.sun.star.style.ParagraphProperties")) { + Short outlineLevel = null; + XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, textContent); + try { + outlineLevel = (Short) properties.getPropertyValue("OutlineLevel"); + } catch (UnknownPropertyException e) { + System.out.println("Shouldn't be here!"); + e.printStackTrace(); + } + if (outlineLevel != null && outlineLevel > 0) { + XTextRange textRange = textContent.getAnchor(); + String name = textRange.getString(); + System.out.println("Outline element found! " + name); + new OutlineElement(textRange); + //TODO: outline element found. Save outline element name and anchor + } + } + } catch (NoSuchElementException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (WrappedTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + private void getCurrentDocument() throws MetadataInaccessableException { currentDocument = xDesktop.getCurrentComponent(); if (currentDocument == null) { @@ -231,6 +288,14 @@ public class Document { } return value; } + + 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/metadata/MetadataElement.java b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java new file mode 100644 index 0000000..d5164b4 --- /dev/null +++ b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java @@ -0,0 +1,43 @@ +package pro.litvinovg.libreoffice.metadata; + +import static pro.litvinovg.libreoffice.metadata.MetadataElement.METADATA_PREFIX; + +public class MetadataElement { + + public static final String METADATA_START = "## Metadata Editor extension. Outline metadata folllows: "; + public static String METADATA_PREFIX = "##"; + public static String METADATA_END = "## Metadata Editor extension. Outline metadata ends."; + + + + private String name; + private String value; + + public MetadataElement(String name, String value) { + this.name = name; + this.value = value; + } + public MetadataElement(String encodedPair) { + //TODO: Parse encoded pair + this.name = ""; + this.value = ""; + } + public String getName() { + return name; + } + + public String getValue() { + return value; + } + public static boolean isValidMetadataString(String cursorContent) { + if (!cursorContent.startsWith(METADATA_PREFIX) || + cursorContent.equals(METADATA_START) || + cursorContent.equals(METADATA_END)){ + return false; + } + String data = cursorContent.substring(cursorContent.lastIndexOf(METADATA_PREFIX)); + + return true; + } + +} diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java new file mode 100644 index 0000000..f22e7b9 --- /dev/null +++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java @@ -0,0 +1,79 @@ +package pro.litvinovg.libreoffice.metadata; + +import java.util.ArrayList; + +import com.sun.star.text.XParagraphCursor; +import com.sun.star.text.XText; +import com.sun.star.text.XTextCursor; +import com.sun.star.text.XTextRange; +import com.sun.star.uno.UnoRuntime; +import static pro.litvinovg.libreoffice.metadata.MetadataElement.*; + +public class OutlineElement { + + private String name; + private ArrayList metadataElements = null; + + public String getName() { + return name; + } + + private XTextRange textRange; + private boolean hasMetadataStorage = false; + private XTextRange metadataTextRange = null; + + public OutlineElement(XTextRange textRange) { + this.textRange = textRange; + this.name = textRange.getString(); + getMetadataStorage(); + } + + private void getMetadataStorage() { + XText curText = textRange.getText(); + XTextCursor cursor = curText.createTextCursorByRange(textRange); + XParagraphCursor paraCursor = UnoRuntime.queryInterface(XParagraphCursor.class, cursor); + readMetadataBody(paraCursor); + if (metadataElements == null) { + metadataElements = new ArrayList(); + } + } + + private void readMetadataBody(XParagraphCursor paraCursor) { + String cursorContent = getNextParaContent(paraCursor); + + if (! cursorContent.equals(METADATA_START)){ + System.out.println("Para doesn't have metadata start header" + cursorContent); + return; + } + ArrayList metadataTempElements = new ArrayList(); + cursorContent = getNextParaContent(paraCursor); + while (cursorContent.startsWith(METADATA_PREFIX)) { + if (cursorContent.equals(METADATA_END)) { + metadataElements = metadataTempElements; + return; + } + if (MetadataElement.isValidMetadataString(cursorContent)) { + metadataTempElements.add(new MetadataElement(cursorContent)); + } else { + //If reading fails exit immediately + return; + } + cursorContent = getNextParaContent(paraCursor); + } + + } + + private String getNextParaContent(XParagraphCursor paraCursor) { + boolean moved = paraCursor.gotoNextParagraph(false); + if (moved == false) { + return ""; + } + moved = paraCursor.gotoEndOfParagraph(true); + if (moved == false) { + return ""; + } + String cursorContent = paraCursor.getString(); + return cursorContent; + } + +} diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index 9ab7fd6..dbeee76 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -44,6 +44,7 @@ import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import javax.swing.JToggleButton; import javax.swing.LayoutStyle.ComponentPlacement; +import javax.swing.JLabel; public class EditorGUI extends JFrame { //Components @@ -190,6 +191,7 @@ public class EditorGUI extends JFrame { tableDocProps.setModel(docPropertiesModel); tableDocCustomProps = new JTable(); + tableDocCustomProps.setColumnSelectionAllowed(true); tableDocCustomProps.putClientProperty("terminateEditOnFocusLost", true); tableDocCustomProps.setSurrendersFocusOnKeystroke(true); @@ -199,32 +201,49 @@ public class EditorGUI extends JFrame { btnNewButton = new JButton("Save"); + JLabel labelDocProperties = new JLabel("Основные метаданные"); + + JLabel labelDocCustomProperties = new JLabel("Дополнительные метаданные"); + GroupLayout gl_panel = new GroupLayout(panel); gl_panel.setHorizontalGroup( - gl_panel.createParallelGroup(Alignment.LEADING) - .addGroup(Alignment.TRAILING, gl_panel.createSequentialGroup() - .addContainerGap(838, Short.MAX_VALUE) - .addComponent(btnNewButton) - .addGap(58)) - .addGroup(gl_panel.createSequentialGroup() + gl_panel.createParallelGroup(Alignment.TRAILING) + .addGroup(Alignment.LEADING, gl_panel.createSequentialGroup() + .addGap(378) + .addComponent(labelDocProperties, GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE) + .addGap(421)) + .addGroup(Alignment.LEADING, gl_panel.createSequentialGroup() + .addContainerGap() + .addGroup(gl_panel.createParallelGroup(Alignment.LEADING) + .addGroup(gl_panel.createSequentialGroup() + .addComponent(tableDocProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(Alignment.TRAILING, gl_panel.createSequentialGroup() + .addComponent(btnNewButton) + .addGap(294)))) + .addGroup(Alignment.LEADING, gl_panel.createSequentialGroup() + .addGap(350) + .addComponent(labelDocCustomProperties, GroupLayout.DEFAULT_SIZE, 233, Short.MAX_VALUE) + .addGap(381)) + .addGroup(Alignment.LEADING, gl_panel.createSequentialGroup() .addContainerGap() .addComponent(tableDocCustomProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) .addContainerGap()) - .addGroup(gl_panel.createSequentialGroup() - .addContainerGap() - .addComponent(tableDocProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) - .addContainerGap()) ); gl_panel.setVerticalGroup( gl_panel.createParallelGroup(Alignment.LEADING) .addGroup(gl_panel.createSequentialGroup() - .addGap(86) + .addGap(53) + .addComponent(labelDocProperties) + .addGap(18) .addComponent(tableDocProps, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) .addPreferredGap(ComponentPlacement.UNRELATED) - .addComponent(tableDocCustomProps, GroupLayout.DEFAULT_SIZE, 368, Short.MAX_VALUE) - .addGap(81) + .addComponent(labelDocCustomProperties, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE) + .addGap(18) + .addComponent(tableDocCustomProps, GroupLayout.PREFERRED_SIZE, 322, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(ComponentPlacement.RELATED, 90, Short.MAX_VALUE) .addComponent(btnNewButton) - .addGap(27)) + .addGap(31)) ); JPopupMenu popupMenu = new JPopupMenu(); @@ -241,9 +260,6 @@ public class EditorGUI extends JFrame { JMenu mnFile = new JMenu("Файл"); menuBar.add(mnFile); - - JMenu mnEdit = new JMenu("Edit"); - menuBar.add(mnEdit); } private void createDocPropsModel() { From cebf79d67e158c1c41162b0e2be8f297634ed005 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 9 Apr 2020 15:38:37 +0200 Subject: [PATCH 08/31] Adding tabs for outline --- source/pro/litvinovg/libreoffice/metadata/Document.java | 7 +++++-- .../litvinovg/libreoffice/metadata/views/EditorGUI.java | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index ce57393..01a6630 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -50,6 +50,7 @@ public class Document { private XDocumentProperties documentProperties; private XDocumentPropertiesSupplier documentPropertiesSupplier; private XText text = null; + private ArrayList outline = new ArrayList(); public Document(XComponentContext componentContext) { context = componentContext; @@ -99,8 +100,7 @@ public class Document { XTextRange textRange = textContent.getAnchor(); String name = textRange.getString(); System.out.println("Outline element found! " + name); - new OutlineElement(textRange); - //TODO: outline element found. Save outline element name and anchor + outline.add(new OutlineElement(textRange)); } } } catch (NoSuchElementException e) { @@ -297,5 +297,8 @@ public class Document { return info.supportsService(service); } + public ArrayList getOutline(){ + return outline; + } } diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index dbeee76..3d625fc 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -27,6 +27,7 @@ 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; @@ -62,6 +63,7 @@ public class EditorGUI extends JFrame { private Document document = null; private JButton btnNewButton; private JMenuItem menuItemPupupDocUserProps; + private ArrayList outline; /** @@ -112,11 +114,13 @@ public class EditorGUI extends JFrame { this.document = doc; docProps = document.getDocumentProperties(); docCustomProps = document.getDocumentCustomProperties(); + outline = document.getOutline(); initComponents(); createEvents(); } public EditorGUI() { + outline = new ArrayList(); initComponents(); createEvents(); } @@ -176,6 +180,10 @@ public class EditorGUI extends JFrame { JPanel panel = new JPanel(); tabbedPane.addTab("Документ", null, panel, null); + for (OutlineElement element : outline) { + tabbedPane.addTab(element.getName(), null, new JPanel(), null); + + } tabbedPane.setEnabledAt(0, true); From da9eb999c163b46c487816ef0496ebc7c9006f81 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 9 Apr 2020 17:16:38 +0200 Subject: [PATCH 09/31] Serialization --- .../libreoffice/metadata/MetadataElement.java | 27 +++--------- .../metadata/MetadataElementFactory.java | 43 +++++++++++++++++++ .../libreoffice/metadata/OutlineElement.java | 17 ++++++-- 3 files changed, 62 insertions(+), 25 deletions(-) create mode 100644 source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java index d5164b4..34edabe 100644 --- a/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java @@ -1,15 +1,11 @@ package pro.litvinovg.libreoffice.metadata; -import static pro.litvinovg.libreoffice.metadata.MetadataElement.METADATA_PREFIX; +import java.io.Serializable; -public class MetadataElement { - - public static final String METADATA_START = "## Metadata Editor extension. Outline metadata folllows: "; - public static String METADATA_PREFIX = "##"; - public static String METADATA_END = "## Metadata Editor extension. Outline metadata ends."; - +public class MetadataElement implements Serializable{ + private static final long serialVersionUID = 1L; private String name; private String value; @@ -17,11 +13,7 @@ public class MetadataElement { this.name = name; this.value = value; } - public MetadataElement(String encodedPair) { - //TODO: Parse encoded pair - this.name = ""; - this.value = ""; - } + public String getName() { return name; } @@ -29,15 +21,6 @@ public class MetadataElement { public String getValue() { return value; } - public static boolean isValidMetadataString(String cursorContent) { - if (!cursorContent.startsWith(METADATA_PREFIX) || - cursorContent.equals(METADATA_START) || - cursorContent.equals(METADATA_END)){ - return false; - } - String data = cursorContent.substring(cursorContent.lastIndexOf(METADATA_PREFIX)); - - return true; - } + } diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java b/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java new file mode 100644 index 0000000..ff3963f --- /dev/null +++ b/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java @@ -0,0 +1,43 @@ +package pro.litvinovg.libreoffice.metadata; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Base64; + +public class MetadataElementFactory { + public static final String METADATA_START = "## Metadata Editor extension. Outline metadata folllows: "; + public static String METADATA_PREFIX = "##"; + public static String METADATA_END = "## Metadata Editor extension. Outline metadata ends."; + + + public static boolean isValidMetadataString(String cursorContent) { + if (!cursorContent.startsWith(METADATA_PREFIX) || + cursorContent.equals(METADATA_START) || + cursorContent.equals(METADATA_END)){ + return false; + } + String data = cursorContent.substring(cursorContent.lastIndexOf(METADATA_PREFIX)); + + return true; + } + + + public static MetadataElement fromString(String string) throws IOException, ClassNotFoundException { + byte [] data = Base64.getDecoder().decode( string ); + ObjectInputStream ois = new ObjectInputStream( new ByteArrayInputStream( data ) ); + Object object = ois.readObject(); + ois.close(); + return (MetadataElement) object; + } + + private static String toString( MetadataElement object ) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream( baos ); + oos.writeObject( object ); + oos.close(); + return Base64.getEncoder().encodeToString(baos.toByteArray()); + } +} diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java index f22e7b9..21ffb42 100644 --- a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java @@ -1,5 +1,6 @@ package pro.litvinovg.libreoffice.metadata; +import java.io.IOException; import java.util.ArrayList; import com.sun.star.text.XParagraphCursor; @@ -7,7 +8,7 @@ import com.sun.star.text.XText; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextRange; import com.sun.star.uno.UnoRuntime; -import static pro.litvinovg.libreoffice.metadata.MetadataElement.*; +import static pro.litvinovg.libreoffice.metadata.MetadataElementFactory.*; public class OutlineElement { @@ -52,8 +53,18 @@ public class OutlineElement { metadataElements = metadataTempElements; return; } - if (MetadataElement.isValidMetadataString(cursorContent)) { - metadataTempElements.add(new MetadataElement(cursorContent)); + if (MetadataElementFactory.isValidMetadataString(cursorContent)) { + MetadataElement metadataElement = null; + try { + metadataElement = MetadataElementFactory.fromString(cursorContent); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + return; + } catch (IOException e) { + e.printStackTrace(); + return; + } + metadataTempElements.add(metadataElement); } else { //If reading fails exit immediately return; From 167555ebbec8eb4189344cc1df31e7ac87271c74 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Tue, 14 Apr 2020 12:23:19 +0200 Subject: [PATCH 10/31] Read annotations content --- .../libreoffice/metadata/Document.java | 89 +++++++++++++---- .../libreoffice/metadata/MetadataElement.java | 4 +- .../metadata/MetadataElementFactory.java | 65 +++++++------ .../libreoffice/metadata/OutlineElement.java | 95 ++++++------------- .../libreoffice/metadata/views/EditorGUI.java | 45 ++++++++- 5 files changed, 178 insertions(+), 120 deletions(-) diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index 01a6630..3a3e85b 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -27,10 +27,12 @@ import com.sun.star.lang.WrappedTargetException; import com.sun.star.lang.XComponent; import com.sun.star.lang.XMultiComponentFactory; 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.XTextDocument; import com.sun.star.text.XTextRange; +import com.sun.star.text.XTextTable; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; @@ -42,6 +44,7 @@ public class Document { private static final String DOC_DESCRIPTION = "Document description"; private static final String DOC_KEYWORDS = "Document keywords"; private static final short REMOVEABLE_ATTRIBUTE = 128; + private static final Object METADATA_EXTENSION = "Metadata Extension"; private XComponentContext context; private XDesktop xDesktop; @@ -75,33 +78,25 @@ public class Document { } private void updateChapterMetadata() { - findAllChapters(); + readMetadataInDocument(); + } - private void findAllChapters() { - XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, text); + private void readMetadataInDocument() { + readMetadataInText(this.text); + } + + private void readMetadataInText(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()); if(isSupported(textContent, "com.sun.star.text.TextTable")) { - //TODO: Go over table to check for outline elements + readMetadataInTable(textContent); } else if (isSupported(textContent, "com.sun.star.style.ParagraphProperties")) { - Short outlineLevel = null; - XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, textContent); - try { - outlineLevel = (Short) properties.getPropertyValue("OutlineLevel"); - } catch (UnknownPropertyException e) { - System.out.println("Shouldn't be here!"); - e.printStackTrace(); - } - if (outlineLevel != null && outlineLevel > 0) { - XTextRange textRange = textContent.getAnchor(); - String name = textRange.getString(); - System.out.println("Outline element found! " + name); - outline.add(new OutlineElement(textRange)); - } + readMetadataInParagraph(textContent); } } catch (NoSuchElementException e) { // TODO Auto-generated catch block @@ -113,6 +108,64 @@ public class Document { } } + private void readMetadataInTable(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(); + readMetadataInText(cellText); + } + } + + private void readMetadataInParagraph(XTextContent textContent) throws WrappedTargetException { + checkOutlineLevel(textContent); + XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, textContent); + XEnumeration paraEnum = enumAccess.createEnumeration(); + while (paraEnum.hasMoreElements()) { + String portionType = null; + try { + XPropertySet portionPoperties = UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, paraEnum.nextElement()); + 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"); + System.out.println("Content " + content); + OutlineElement lastElement = outline.get(outline.size()-1); + lastElement.readMetadata(content); + } + } + } catch (NoSuchElementException e) { + e.printStackTrace(); + } catch (WrappedTargetException e) { + e.printStackTrace(); + } catch (UnknownPropertyException e) { + e.printStackTrace(); + } + + } + + + } + + private void checkOutlineLevel(XTextContent textContent) throws WrappedTargetException { + Short outlineLevel = null; + XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, textContent); + try { + outlineLevel = (Short) properties.getPropertyValue("OutlineLevel"); + } catch (UnknownPropertyException e) { + e.printStackTrace(); + } + if (outlineLevel != null && outlineLevel > 0) { + XTextRange textRange = textContent.getAnchor(); + outline.add(new OutlineElement(textRange)); + } + } + private void getCurrentDocument() throws MetadataInaccessableException { currentDocument = xDesktop.getCurrentComponent(); if (currentDocument == null) { diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java index 34edabe..6cd6326 100644 --- a/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java @@ -2,10 +2,8 @@ package pro.litvinovg.libreoffice.metadata; import java.io.Serializable; -public class MetadataElement implements Serializable{ +public class MetadataElement { - - private static final long serialVersionUID = 1L; private String name; private String value; diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java b/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java index ff3963f..5bc37f7 100644 --- a/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java +++ b/source/pro/litvinovg/libreoffice/metadata/MetadataElementFactory.java @@ -1,43 +1,42 @@ package pro.litvinovg.libreoffice.metadata; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Base64; +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 folllows: "; - public static String METADATA_PREFIX = "##"; - public static String METADATA_END = "## Metadata Editor extension. Outline metadata ends."; + 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 boolean isValidMetadataString(String cursorContent) { - if (!cursorContent.startsWith(METADATA_PREFIX) || - cursorContent.equals(METADATA_START) || - cursorContent.equals(METADATA_END)){ - return false; - } - String data = cursorContent.substring(cursorContent.lastIndexOf(METADATA_PREFIX)); + 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) { - return true; - } - - - public static MetadataElement fromString(String string) throws IOException, ClassNotFoundException { - byte [] data = Base64.getDecoder().decode( string ); - ObjectInputStream ois = new ObjectInputStream( new ByteArrayInputStream( data ) ); - Object object = ois.readObject(); - ois.close(); - return (MetadataElement) object; + JSONObject json = new JSONObject(); + json.put(element.getName(), element.getValue()); + return METADATA_PREFIX + json.toString(); } - private static String toString( MetadataElement object ) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream( baos ); - oos.writeObject( object ); - oos.close(); - return Base64.getEncoder().encodeToString(baos.toByteArray()); - } + public boolean isJSONValid(String test) { + try { + new JSONObject(test); + } catch (JSONException e) { + return false; + } + return true; +} + + + } diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java index 21ffb42..a98beb7 100644 --- a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java @@ -1,20 +1,19 @@ package pro.litvinovg.libreoffice.metadata; -import java.io.IOException; import java.util.ArrayList; +import java.util.Iterator; + +import org.json.JSONException; +import org.json.JSONObject; + -import com.sun.star.text.XParagraphCursor; -import com.sun.star.text.XText; -import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextRange; -import com.sun.star.uno.UnoRuntime; -import static pro.litvinovg.libreoffice.metadata.MetadataElementFactory.*; public class OutlineElement { private String name; - private ArrayList metadataElements = null; - + private ArrayList metadata = null; + public String getName() { return name; } @@ -22,69 +21,37 @@ public class OutlineElement { private XTextRange textRange; private boolean hasMetadataStorage = false; private XTextRange metadataTextRange = null; - + public OutlineElement(XTextRange textRange) { this.textRange = textRange; this.name = textRange.getString(); - getMetadataStorage(); + this.metadata = new ArrayList(); } - private void getMetadataStorage() { - XText curText = textRange.getText(); - XTextCursor cursor = curText.createTextCursorByRange(textRange); - XParagraphCursor paraCursor = UnoRuntime.queryInterface(XParagraphCursor.class, cursor); - readMetadataBody(paraCursor); - if (metadataElements == null) { - metadataElements = new ArrayList(); - } - } - - private void readMetadataBody(XParagraphCursor paraCursor) { - String cursorContent = getNextParaContent(paraCursor); - - if (! cursorContent.equals(METADATA_START)){ - System.out.println("Para doesn't have metadata start header" + cursorContent); - return; - } - ArrayList metadataTempElements = new ArrayList(); - cursorContent = getNextParaContent(paraCursor); - while (cursorContent.startsWith(METADATA_PREFIX)) { - if (cursorContent.equals(METADATA_END)) { - metadataElements = metadataTempElements; - return; + public void readMetadata(String data) { + try { + JSONObject json = new JSONObject(data); + Iterator names = json.keys(); + while (names.hasNext()) { + String metaName = names.next(); + String metaValue = (String) json.get(metaName); + metadata.add(new MetadataElement(metaName, metaValue)); } - if (MetadataElementFactory.isValidMetadataString(cursorContent)) { - MetadataElement metadataElement = null; - try { - metadataElement = MetadataElementFactory.fromString(cursorContent); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - return; - } catch (IOException e) { - e.printStackTrace(); - return; - } - metadataTempElements.add(metadataElement); - } else { - //If reading fails exit immediately - return; - } - cursorContent = getNextParaContent(paraCursor); + } catch (JSONException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); } - - } - - private String getNextParaContent(XParagraphCursor paraCursor) { - boolean moved = paraCursor.gotoNextParagraph(false); - if (moved == false) { - return ""; - } - moved = paraCursor.gotoEndOfParagraph(true); - if (moved == false) { - return ""; - } - String cursorContent = paraCursor.getString(); - return cursorContent; } +public String toString() { + JSONObject json = new JSONObject(); + for (MetadataElement element : metadata) { + json.put(element.getName(), element.getValue()); + } + return json.toString(); + } + + + } diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index 3d625fc..c786fba 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -56,6 +56,7 @@ public class EditorGUI extends JFrame { //Component models private DefaultTableModel docPropertiesModel; private DefaultTableModel docCustomPropsModel; + private DefaultTableModel outlineTableModel; private Map docProps; @@ -64,6 +65,8 @@ public class EditorGUI extends JFrame { private JButton btnNewButton; private JMenuItem menuItemPupupDocUserProps; private ArrayList outline; + private JTable tableOutline; + private JPanel panelForOutline; /** @@ -181,9 +184,37 @@ public class EditorGUI extends JFrame { JPanel panel = new JPanel(); tabbedPane.addTab("Документ", null, panel, null); for (OutlineElement element : outline) { - tabbedPane.addTab(element.getName(), null, new JPanel(), null); - + JPanel panelForOutline = new JPanel(); + tabbedPane.addTab(element.getName(), null, panelForOutline, null); } + panelForOutline = new JPanel(); + tabbedPane.addTab("секция", null, panelForOutline, null); + + tableOutline = new JTable(); + createOutlineTableModel(); + tableOutline.setModel(outlineTableModel); + tableOutline.putClientProperty("terminateEditOnFocusLost", true); + tableOutline.setSurrendersFocusOnKeystroke(true); + tableOutline.setCellSelectionEnabled(true); + tableOutline.setFillsViewportHeight(true); + + GroupLayout gl_panelForOutline = new GroupLayout(panelForOutline); + gl_panelForOutline.setHorizontalGroup( + gl_panelForOutline.createParallelGroup(Alignment.LEADING) + .addGroup(gl_panelForOutline.createSequentialGroup() + .addGap(34) + .addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 804, Short.MAX_VALUE) + .addGap(126)) + ); + gl_panelForOutline.setVerticalGroup( + gl_panelForOutline.createParallelGroup(Alignment.LEADING) + .addGroup(gl_panelForOutline.createSequentialGroup() + .addGap(85) + .addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 475, Short.MAX_VALUE) + .addGap(120)) + ); + panelForOutline.setLayout(gl_panelForOutline); + tabbedPane.setEnabledAt(0, true); @@ -294,6 +325,16 @@ public class EditorGUI extends JFrame { }); } + private void createOutlineTableModel() { + outlineTableModel = new DefaultTableModel( + new Object[][] { + {null, null}, + }, + new String[] { + "New column", "New column" + } + ); + } private void createCustomDocPropsModel() { Object[][] tableArray = new Object[][] { {null, null}, From e7f4f3c46ec0fa8bf4450034d20e7a56c04500b3 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Wed, 15 Apr 2020 16:19:03 +0200 Subject: [PATCH 11/31] Save annotation range in outline object --- .../pro/litvinovg/libreoffice/metadata/Document.java | 3 +-- .../libreoffice/metadata/OutlineElement.java | 11 ++++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index 3a3e85b..4be3964 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -134,11 +134,10 @@ public class Document { String author = (String) annotationProperties.getPropertyValue("Author"); if (author != null && author.equals(METADATA_EXTENSION)) { String content = (String) annotationProperties.getPropertyValue("Content"); - System.out.println("Content " + content); OutlineElement lastElement = outline.get(outline.size()-1); lastElement.readMetadata(content); } - } + } } catch (NoSuchElementException e) { e.printStackTrace(); } catch (WrappedTargetException e) { diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java index a98beb7..a02ab16 100644 --- a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java @@ -20,14 +20,19 @@ public class OutlineElement { private XTextRange textRange; private boolean hasMetadataStorage = false; - private XTextRange metadataTextRange = null; + private XTextRange annotationStart = null; + private XTextRange annotationEnd = null; public OutlineElement(XTextRange textRange) { this.textRange = textRange; this.name = textRange.getString(); this.metadata = new ArrayList(); + annotationStart = textRange.getStart(); } - + public void setAnnotationAnchorEnd(XTextRange anchor) { + this.annotationEnd = anchor; + } + public void readMetadata(String data) { try { JSONObject json = new JSONObject(data); @@ -44,7 +49,7 @@ public class OutlineElement { } } -public String toString() { +public String metadataToString() { JSONObject json = new JSONObject(); for (MetadataElement element : metadata) { json.put(element.getName(), element.getValue()); From 76859c54db702c39542984c5077d250b847046c7 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Wed, 15 Apr 2020 19:53:47 +0200 Subject: [PATCH 12/31] End of the day commit --- .../litvinovg/libreoffice/DocumentParser.java | 6 + .../libreoffice/DocumentParserImpl.java | 90 +++++++++++++ .../libreoffice/MetadataCleaner.java | 47 +++++++ .../litvinovg/libreoffice/MetadataReader.java | 69 ++++++++++ .../libreoffice/metadata/Document.java | 126 ++++-------------- .../libreoffice/metadata/OutlineElement.java | 43 +++++- 6 files changed, 274 insertions(+), 107 deletions(-) create mode 100644 source/pro/litvinovg/libreoffice/DocumentParser.java create mode 100644 source/pro/litvinovg/libreoffice/DocumentParserImpl.java create mode 100644 source/pro/litvinovg/libreoffice/MetadataCleaner.java create mode 100644 source/pro/litvinovg/libreoffice/MetadataReader.java 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..74f639a --- /dev/null +++ b/source/pro/litvinovg/libreoffice/MetadataReader.java @@ -0,0 +1,69 @@ +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; + + public MetadataReader(XText text, ArrayList outline) { + super(text); + this.outline = outline; + } + @Override + public void parse() { + parseText(text); + OutlineElement lastElement = outline.get(outline.size()-1); + lastElement.setAnnotationEnd(documentEnd); + } + + @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 (outlineLevel != null && outlineLevel > 0) { + XTextRange textRange = textContent.getAnchor(); + OutlineElement lastElement = outline.get(outline.size()-1); + lastElement.setAnnotationEnd(textContent.getAnchor().getStart()); + outline.add(new OutlineElement(textRange)); + } + } +} diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index 4be3964..f8fbb12 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -1,13 +1,11 @@ package pro.litvinovg.libreoffice.metadata; -import java.nio.file.attribute.UserDefinedFileAttributeView; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.Map; -import com.sun.org.apache.bcel.internal.generic.NEW; import com.sun.star.beans.IllegalTypeException; import com.sun.star.beans.NotRemoveableException; import com.sun.star.beans.Property; @@ -16,26 +14,22 @@ 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.container.NoSuchElementException; -import com.sun.star.container.XEnumeration; -import com.sun.star.container.XEnumerationAccess; import com.sun.star.document.XDocumentProperties; import com.sun.star.document.XDocumentPropertiesSupplier; import com.sun.star.frame.XDesktop; 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.XServiceInfo; -import com.sun.star.table.XCell; +import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.text.XText; -import com.sun.star.text.XTextContent; import com.sun.star.text.XTextDocument; -import com.sun.star.text.XTextRange; -import com.sun.star.text.XTextTable; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; +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"; @@ -44,11 +38,12 @@ public class Document { private static final String DOC_DESCRIPTION = "Document description"; private static final String DOC_KEYWORDS = "Document keywords"; private static final short REMOVEABLE_ATTRIBUTE = 128; - private static final Object METADATA_EXTENSION = "Metadata Extension"; + 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; @@ -63,13 +58,13 @@ public class Document { xDesktop = UnoRuntime.queryInterface(XDesktop.class, oDesktop); getCurrentDocument(); getDocumentText(); - updateChapterMetadata(); + multiServiceFactory = UnoRuntime.queryInterface(XMultiServiceFactory.class, currentDocument); + readMetadataInDocument(); } catch (Exception e) { System.out.println("xDesktop inaccessible. Can not proceed."); e.printStackTrace(); System.exit(1); } - //logProperties(); } private void getDocumentText() { @@ -77,94 +72,29 @@ public class Document { text = textDocument.getText(); } - private void updateChapterMetadata() { - readMetadataInDocument(); - - } - private void readMetadataInDocument() { - readMetadataInText(this.text); + DocumentParser reader = new MetadataReader(text, outline); + reader.parse(); } - - private void readMetadataInText(XText curText) { - XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, curText); - XEnumeration textEnum = enumAccess.createEnumeration(); - while (textEnum.hasMoreElements()) { + + private void cleanMetadataInDocument() { + DocumentParser reader = new MetadataCleaner(text); + reader.parse(); + } + + private void writeMetadata() { + cleanMetadataInDocument(); + for (OutlineElement element : outline){ + Object annotation; try { - XTextContent textContent = UnoRuntime.queryInterface(XTextContent.class, textEnum.nextElement()); - if(isSupported(textContent, "com.sun.star.text.TextTable")) { - readMetadataInTable(textContent); - } else - if (isSupported(textContent, "com.sun.star.style.ParagraphProperties")) { - readMetadataInParagraph(textContent); - } - } catch (NoSuchElementException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (WrappedTargetException e) { - // TODO Auto-generated catch block + annotation = multiServiceFactory.createInstance("com.sun.star.text.textfield.nnotation"); + element.writeMetadata(annotation); + } catch (com.sun.star.uno.Exception e) { e.printStackTrace(); } } } - private void readMetadataInTable(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(); - readMetadataInText(cellText); - } - } - - private void readMetadataInParagraph(XTextContent textContent) throws WrappedTargetException { - checkOutlineLevel(textContent); - XEnumerationAccess enumAccess = UnoRuntime.queryInterface(XEnumerationAccess.class, textContent); - XEnumeration paraEnum = enumAccess.createEnumeration(); - while (paraEnum.hasMoreElements()) { - String portionType = null; - try { - XPropertySet portionPoperties = UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, paraEnum.nextElement()); - 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 (NoSuchElementException e) { - e.printStackTrace(); - } catch (WrappedTargetException e) { - e.printStackTrace(); - } catch (UnknownPropertyException e) { - e.printStackTrace(); - } - - } - - - } - - private void checkOutlineLevel(XTextContent textContent) throws WrappedTargetException { - Short outlineLevel = null; - XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, textContent); - try { - outlineLevel = (Short) properties.getPropertyValue("OutlineLevel"); - } catch (UnknownPropertyException e) { - e.printStackTrace(); - } - if (outlineLevel != null && outlineLevel > 0) { - XTextRange textRange = textContent.getAnchor(); - outline.add(new OutlineElement(textRange)); - } - } - private void getCurrentDocument() throws MetadataInaccessableException { currentDocument = xDesktop.getCurrentComponent(); if (currentDocument == null) { @@ -341,14 +271,6 @@ public class Document { return value; } - private boolean isSupported(Object object, String service) { - XServiceInfo info = UnoRuntime.queryInterface(XServiceInfo.class, object); - if (info == null) { - return false; - } - return info.supportsService(service); - - } public ArrayList getOutline(){ return outline; } diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java index a02ab16..e394269 100644 --- a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java @@ -6,9 +6,17 @@ import java.util.Iterator; 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 name; @@ -19,7 +27,6 @@ public class OutlineElement { } private XTextRange textRange; - private boolean hasMetadataStorage = false; private XTextRange annotationStart = null; private XTextRange annotationEnd = null; @@ -29,7 +36,7 @@ public class OutlineElement { this.metadata = new ArrayList(); annotationStart = textRange.getStart(); } - public void setAnnotationAnchorEnd(XTextRange anchor) { + public void setAnnotationEnd(XTextRange anchor) { this.annotationEnd = anchor; } @@ -49,13 +56,39 @@ public class OutlineElement { } } -public String metadataToString() { +private String metadataToString() { JSONObject json = new JSONObject(); for (MetadataElement element : metadata) { json.put(element.getName(), element.getValue()); } return json.toString(); } +public void writeMetadata(Object annotation) { + XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, annotation); + XText startText = annotationStart.getText(); + try { + properties.setPropertyValue("Author", METADATA_EXTENSION); + properties.setPropertyValue("Content", metadataToString()); + XTextRange annotationRange = null; + if (startText.equals(annotationEnd.getText())){ + XTextCursor cursor = startText.createTextCursorByRange(annotationStart); + cursor.gotoRange(annotationEnd, true); + annotationRange = UnoRuntime.queryInterface(XTextRange.class, cursor); + } else { + annotationRange = textRange; + } + XTextField textField = UnoRuntime.queryInterface(XTextField.class, annotation); + startText.insertTextContent( annotationRange, textField, true ); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (UnknownPropertyException e) { + e.printStackTrace(); + } catch (PropertyVetoException e) { + e.printStackTrace(); + } catch (WrappedTargetException e) { + e.printStackTrace(); + } +} From adf19bc4ab26549a2029e7fb87bb21671d88756a Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 16 Apr 2020 14:08:29 +0200 Subject: [PATCH 13/31] Working on GUI --- .../litvinovg/libreoffice/MetadataReader.java | 13 +- .../libreoffice/metadata/Document.java | 4 +- .../libreoffice/metadata/OutlineElement.java | 48 ++-- .../libreoffice/metadata/views/EditorGUI.java | 265 ++++++++++-------- 4 files changed, 190 insertions(+), 140 deletions(-) diff --git a/source/pro/litvinovg/libreoffice/MetadataReader.java b/source/pro/litvinovg/libreoffice/MetadataReader.java index 74f639a..cbc6d2e 100644 --- a/source/pro/litvinovg/libreoffice/MetadataReader.java +++ b/source/pro/litvinovg/libreoffice/MetadataReader.java @@ -15,6 +15,7 @@ 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); @@ -24,7 +25,6 @@ public class MetadataReader extends DocumentParserImpl { public void parse() { parseText(text); OutlineElement lastElement = outline.get(outline.size()-1); - lastElement.setAnnotationEnd(documentEnd); } @Override @@ -59,11 +59,14 @@ public class MetadataReader extends DocumentParserImpl { } catch (WrappedTargetException e) { e.printStackTrace(); } - if (outlineLevel != null && outlineLevel > 0) { + if (firstPara || (outlineLevel != null && outlineLevel > 0)) { XTextRange textRange = textContent.getAnchor(); - OutlineElement lastElement = outline.get(outline.size()-1); - lastElement.setAnnotationEnd(textContent.getAnchor().getStart()); - outline.add(new OutlineElement(textRange)); + 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/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index f8fbb12..6a41280 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -82,12 +82,12 @@ public class Document { reader.parse(); } - private void writeMetadata() { + private void writeOutlineMetadata() { cleanMetadataInDocument(); for (OutlineElement element : outline){ Object annotation; try { - annotation = multiServiceFactory.createInstance("com.sun.star.text.textfield.nnotation"); + annotation = multiServiceFactory.createInstance("com.sun.star.text.textfield.annotation"); element.writeMetadata(annotation); } catch (com.sun.star.uno.Exception e) { e.printStackTrace(); diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java index e394269..ed4488e 100644 --- a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java @@ -19,25 +19,38 @@ import com.sun.star.uno.UnoRuntime; import static pro.litvinovg.libreoffice.metadata.Document.*; public class OutlineElement { - private String name; + private String elementName; private ArrayList metadata = null; public String getName() { - return name; + return elementName; } private XTextRange textRange; - private XTextRange annotationStart = null; - private XTextRange annotationEnd = null; - public OutlineElement(XTextRange textRange) { + public OutlineElement(XTextRange textRange, String name) { this.textRange = textRange; - this.name = textRange.getString(); + this.elementName = name; this.metadata = new ArrayList(); - annotationStart = textRange.getStart(); } - public void setAnnotationEnd(XTextRange anchor) { - this.annotationEnd = anchor; + + public Object[][] metadataToArray() { + Object [] [] result = null; + int size = metadata.size(); + if (metadata.size() == 0) { + result = new Object[][] { + {null, null}, + {null, null}, + {null, null}, + }; + } 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) { @@ -59,24 +72,23 @@ public class OutlineElement { private String metadataToString() { JSONObject json = new JSONObject(); for (MetadataElement element : metadata) { - json.put(element.getName(), element.getValue()); + String name = element.getName(); + String value = element.getValue(); + if (!name.isEmpty() && !value.isEmpty()) { + json.put(element.getName(), element.getValue()); + } } return json.toString(); } + public void writeMetadata(Object annotation) { XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, annotation); - XText startText = annotationStart.getText(); + XText startText = textRange.getText(); try { properties.setPropertyValue("Author", METADATA_EXTENSION); properties.setPropertyValue("Content", metadataToString()); XTextRange annotationRange = null; - if (startText.equals(annotationEnd.getText())){ - XTextCursor cursor = startText.createTextCursorByRange(annotationStart); - cursor.gotoRange(annotationEnd, true); - annotationRange = UnoRuntime.queryInterface(XTextRange.class, cursor); - } else { - annotationRange = textRange; - } + annotationRange = textRange; XTextField textField = UnoRuntime.queryInterface(XTextField.class, annotation); startText.insertTextContent( annotationRange, textField, true ); } catch (IllegalArgumentException e) { diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index c786fba..21243f6 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -49,24 +49,27 @@ import javax.swing.JLabel; public class EditorGUI extends JFrame { //Components - private JTable tableDocProps; - private JTable tableDocCustomProps; + private JTable tableDocStandard; + private JTable tableDocCustom; //Component models private DefaultTableModel docPropertiesModel; private DefaultTableModel docCustomPropsModel; - private DefaultTableModel outlineTableModel; + //GroupLayouts + + private Map docProps; private ArrayList docCustomProps; private Document document = null; - private JButton btnNewButton; + private JButton btnSaveButton; private JMenuItem menuItemPupupDocUserProps; private ArrayList outline; - private JTable tableOutline; - private JPanel panelForOutline; + private JTabbedPane tabbedPane; + private JPanel panelStandardMetadata; + private JMenuBar menuBar; /** @@ -129,12 +132,10 @@ public class EditorGUI extends JFrame { } private void createEvents() { - btnNewButton.addActionListener(new ActionListener() { + + btnSaveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - updateDocProps(); - document.setDocumentProperties(docProps); - updateDocCustomProps(); - document.setCustomDocumentProperties(docCustomProps); + saveAction(); } }); @@ -170,135 +171,163 @@ public class EditorGUI extends JFrame { } } private void initComponents() { - setIconImage(Toolkit.getDefaultToolkit().getImage(EditorGUI.class.getResource("/pro/litvinovg/libreoffice/metadata/resources/webcam.png"))); - setTitle("Редактор метаданных"); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setBounds(100, 100, 1064, 733); - getContentPane().setLayout(null); - getContentPane().setLayout(new GridLayout(0, 1, 0, 0)); - - JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.LEFT, JTabbedPane.SCROLL_TAB_LAYOUT); - tabbedPane.setBounds(125, 138, 913, 546); - getContentPane().add(tabbedPane); - - JPanel panel = new JPanel(); - tabbedPane.addTab("Документ", null, panel, null); - for (OutlineElement element : outline) { - JPanel panelForOutline = new JPanel(); - tabbedPane.addTab(element.getName(), null, panelForOutline, null); + configureWindow(); + panelStandardMetadata = new JPanel(); + tabbedPane.addTab("Метаданные либры", null, panelStandardMetadata, null); + tabbedPane.setEnabledAt(0, true); + if (true) { + //TEST ONLY + addMetadataTab(new OutlineElement(null, "Тестовое название")); + } + for (OutlineElement element : outline) { + addMetadataTab(element); } - panelForOutline = new JPanel(); - tabbedPane.addTab("секция", null, panelForOutline, null); - tableOutline = new JTable(); - createOutlineTableModel(); + createDocPropsModel(); + createCustomDocPropsModel(); + tableDocStandard = new JTable(); + tableDocCustom = new JTable(); + 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(); + JTable tableOutline = new JTable(); + DefaultTableModel outlineTableModel = createOutlineTableModel(element); + configureTableOutline(tableOutline, outlineTableModel); + + JButton btnOutlineSave = new JButton("Сохранить"); + btnOutlineSave.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + saveAction(); + } + }); + + GroupLayout groupLayoutOutlineMetadata = new GroupLayout(panelOutline); + groupLayoutOutlineMetadata.setHorizontalGroup( + groupLayoutOutlineMetadata.createParallelGroup(Alignment.LEADING) + .addGroup(groupLayoutOutlineMetadata.createSequentialGroup() + .addGap(34) + .addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 839, Short.MAX_VALUE) + .addGap(126)) + .addGroup(Alignment.TRAILING, groupLayoutOutlineMetadata.createSequentialGroup() + .addContainerGap(748, Short.MAX_VALUE) + .addComponent(btnOutlineSave) + .addGap(134)) + ); + groupLayoutOutlineMetadata.setVerticalGroup( + groupLayoutOutlineMetadata.createParallelGroup(Alignment.LEADING) + .addGroup(groupLayoutOutlineMetadata.createSequentialGroup() + .addGap(85) + .addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 497, Short.MAX_VALUE) + .addGap(52) + .addComponent(btnOutlineSave) + .addGap(43)) + ); + 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); - - GroupLayout gl_panelForOutline = new GroupLayout(panelForOutline); - gl_panelForOutline.setHorizontalGroup( - gl_panelForOutline.createParallelGroup(Alignment.LEADING) - .addGroup(gl_panelForOutline.createSequentialGroup() - .addGap(34) - .addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 804, Short.MAX_VALUE) - .addGap(126)) - ); - gl_panelForOutline.setVerticalGroup( - gl_panelForOutline.createParallelGroup(Alignment.LEADING) - .addGroup(gl_panelForOutline.createSequentialGroup() - .addGap(85) - .addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 475, Short.MAX_VALUE) - .addGap(120)) - ); - panelForOutline.setLayout(gl_panelForOutline); - - tabbedPane.setEnabledAt(0, true); - - - createDocPropsModel(); - createCustomDocPropsModel(); - - - tableDocProps = new JTable(); - tableDocProps.putClientProperty("terminateEditOnFocusLost", true); - tableDocProps.setSurrendersFocusOnKeystroke(true); - tableDocProps.setCellSelectionEnabled(true); - tableDocProps.setFillsViewportHeight(true); - tableDocProps.setModel(docPropertiesModel); - - tableDocCustomProps = new JTable(); - tableDocCustomProps.setColumnSelectionAllowed(true); - tableDocCustomProps.putClientProperty("terminateEditOnFocusLost", true); + } - tableDocCustomProps.setSurrendersFocusOnKeystroke(true); - tableDocCustomProps.setFillsViewportHeight(true); - tableDocCustomProps.setCellSelectionEnabled(true); - tableDocCustomProps.setModel(docCustomPropsModel); - - btnNewButton = new JButton("Save"); + private void configureWindow() { + setIconImage(Toolkit.getDefaultToolkit().getImage(EditorGUI.class.getResource("/pro/litvinovg/libreoffice/metadata/resources/webcam.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("Дополнительные метаданные"); - - GroupLayout gl_panel = new GroupLayout(panel); - gl_panel.setHorizontalGroup( - gl_panel.createParallelGroup(Alignment.TRAILING) - .addGroup(Alignment.LEADING, gl_panel.createSequentialGroup() + 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_panel.createSequentialGroup() + .addGroup(Alignment.LEADING, gl_panelStandardMetadata.createSequentialGroup() .addContainerGap() - .addGroup(gl_panel.createParallelGroup(Alignment.LEADING) - .addGroup(gl_panel.createSequentialGroup() - .addComponent(tableDocProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) + .addGroup(gl_panelStandardMetadata.createParallelGroup(Alignment.LEADING) + .addGroup(gl_panelStandardMetadata.createSequentialGroup() + .addComponent(tableDocStandard, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) .addContainerGap()) - .addGroup(Alignment.TRAILING, gl_panel.createSequentialGroup() - .addComponent(btnNewButton) - .addGap(294)))) - .addGroup(Alignment.LEADING, gl_panel.createSequentialGroup() + .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_panel.createSequentialGroup() + .addGroup(Alignment.LEADING, gl_panelStandardMetadata.createSequentialGroup() .addContainerGap() - .addComponent(tableDocCustomProps, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) + .addComponent(tableDocCustom, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE) .addContainerGap()) ); - gl_panel.setVerticalGroup( - gl_panel.createParallelGroup(Alignment.LEADING) - .addGroup(gl_panel.createSequentialGroup() + gl_panelStandardMetadata.setVerticalGroup( + gl_panelStandardMetadata.createParallelGroup(Alignment.LEADING) + .addGroup(gl_panelStandardMetadata.createSequentialGroup() .addGap(53) .addComponent(labelDocProperties) .addGap(18) - .addComponent(tableDocProps, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addComponent(tableDocStandard, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) .addPreferredGap(ComponentPlacement.UNRELATED) .addComponent(labelDocCustomProperties, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE) .addGap(18) - .addComponent(tableDocCustomProps, GroupLayout.PREFERRED_SIZE, 322, GroupLayout.PREFERRED_SIZE) + .addComponent(tableDocCustom, GroupLayout.PREFERRED_SIZE, 322, GroupLayout.PREFERRED_SIZE) .addPreferredGap(ComponentPlacement.RELATED, 90, Short.MAX_VALUE) - .addComponent(btnNewButton) + .addComponent(btnSaveButton) .addGap(31)) ); - - JPopupMenu popupMenu = new JPopupMenu(); - addPopup(tableDocCustomProps, popupMenu); - - menuItemPupupDocUserProps = new JMenuItem("Добавить строку"); - - popupMenu.add(menuItemPupupDocUserProps); - panel.setLayout(gl_panel); - - - JMenuBar menuBar = new JMenuBar(); - setJMenuBar(menuBar); - - JMenu mnFile = new JMenu("Файл"); - menuBar.add(mnFile); } private void createDocPropsModel() { @@ -325,15 +354,15 @@ public class EditorGUI extends JFrame { }); } - private void createOutlineTableModel() { - outlineTableModel = new DefaultTableModel( - new Object[][] { - {null, null}, - }, + private DefaultTableModel createOutlineTableModel(OutlineElement element) { + + DefaultTableModel outlineTableModel = new DefaultTableModel( + element.metadataToArray(), new String[] { - "New column", "New column" + "Metadata Name", "Metadata Value" } ); + return outlineTableModel; } private void createCustomDocPropsModel() { Object[][] tableArray = new Object[][] { @@ -375,4 +404,10 @@ public class EditorGUI extends JFrame { } }); } + public void saveAction() { + updateDocProps(); + document.setDocumentProperties(docProps); + updateDocCustomProps(); + document.setCustomDocumentProperties(docCustomProps); + } } From 90617b8120a2ca5621edab217e0e71ec1d9cc6fe Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 16 Apr 2020 16:12:40 +0200 Subject: [PATCH 14/31] Alpha working --- .../libreoffice/metadata/Document.java | 18 +++++----- .../libreoffice/metadata/OutlineElement.java | 31 ++++++++++++----- .../libreoffice/metadata/views/EditorGUI.java | 25 ++++++++------ .../metadata/views/MetadataTableModel.java | 34 +++++++++++++++++++ 4 files changed, 81 insertions(+), 27 deletions(-) create mode 100644 source/pro/litvinovg/libreoffice/metadata/views/MetadataTableModel.java diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index 6a41280..d18dd0f 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -82,16 +82,18 @@ public class Document { reader.parse(); } - private void writeOutlineMetadata() { + public void writeOutlineMetadata() { cleanMetadataInDocument(); for (OutlineElement element : outline){ - Object annotation; - try { - annotation = multiServiceFactory.createInstance("com.sun.star.text.textfield.annotation"); - element.writeMetadata(annotation); - } catch (com.sun.star.uno.Exception e) { - e.printStackTrace(); - } + 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(); + } + } } } diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java index ed4488e..d57f958 100644 --- a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java @@ -21,12 +21,22 @@ public class OutlineElement { private String elementName; private ArrayList metadata = null; - + private XTextRange textRange; + public String getName() { return elementName; } - - private XTextRange textRange; + 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; @@ -39,9 +49,9 @@ public class OutlineElement { int size = metadata.size(); if (metadata.size() == 0) { result = new Object[][] { - {null, null}, - {null, null}, - {null, null}, + {"", ""}, + {"", ""}, + {"", ""}, }; } else { result = new Object [size] [2]; @@ -83,14 +93,15 @@ private String metadataToString() { public void writeMetadata(Object annotation) { XPropertySet properties = UnoRuntime.queryInterface(XPropertySet.class, annotation); - XText startText = textRange.getText(); + 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); - startText.insertTextContent( annotationRange, textField, true ); + text.insertTextContent( annotationRange, textField, false ); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (UnknownPropertyException e) { @@ -101,6 +112,10 @@ public void writeMetadata(Object annotation) { e.printStackTrace(); } } +public void setMetadata(ArrayList metadataInput) { + this.metadata.clear(); + this.metadata.addAll(metadataInput); +} diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index 21243f6..5fc0653 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -51,7 +51,7 @@ public class EditorGUI extends JFrame { //Components private JTable tableDocStandard; private JTable tableDocCustom; - + private ArrayList tableModels ; //Component models private DefaultTableModel docPropertiesModel; @@ -121,6 +121,7 @@ public class EditorGUI extends JFrame { docProps = document.getDocumentProperties(); docCustomProps = document.getDocumentCustomProperties(); outline = document.getOutline(); + tableModels = new ArrayList(); initComponents(); createEvents(); } @@ -176,7 +177,6 @@ public class EditorGUI extends JFrame { tabbedPane.addTab("Метаданные либры", null, panelStandardMetadata, null); tabbedPane.setEnabledAt(0, true); if (true) { - //TEST ONLY addMetadataTab(new OutlineElement(null, "Тестовое название")); } for (OutlineElement element : outline) { @@ -213,7 +213,8 @@ public class EditorGUI extends JFrame { private void addMetadataTab(OutlineElement element) { JPanel panelOutline = new JPanel(); JTable tableOutline = new JTable(); - DefaultTableModel outlineTableModel = createOutlineTableModel(element); + MetadataTableModel outlineTableModel = createOutlineTableModel(element); + tableModels.add(outlineTableModel); configureTableOutline(tableOutline, outlineTableModel); JButton btnOutlineSave = new JButton("Сохранить"); @@ -354,14 +355,9 @@ public class EditorGUI extends JFrame { }); } - private DefaultTableModel createOutlineTableModel(OutlineElement element) { + private MetadataTableModel createOutlineTableModel(OutlineElement element) { - DefaultTableModel outlineTableModel = new DefaultTableModel( - element.metadataToArray(), - new String[] { - "Metadata Name", "Metadata Value" - } - ); + MetadataTableModel outlineTableModel = new MetadataTableModel(element); return outlineTableModel; } private void createCustomDocPropsModel() { @@ -387,7 +383,7 @@ public class EditorGUI extends JFrame { } - private static void addPopup(Component component, final JPopupMenu popup) { + private static void addPopup(Component component, JPopupMenu popup) { component.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { if (e.isPopupTrigger()) { @@ -409,5 +405,12 @@ public class EditorGUI extends JFrame { document.setDocumentProperties(docProps); updateDocCustomProps(); document.setCustomDocumentProperties(docCustomProps); + updateOutlineMetadata(); + document.writeOutlineMetadata(); + } + private void updateOutlineMetadata() { + for (MetadataTableModel table : tableModels) { + table.writeToOutline(); + } } } 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..66e092e --- /dev/null +++ b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableModel.java @@ -0,0 +1,34 @@ +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.isEmpty() && !value.isEmpty()) { + metadata.add(new MetadataElement(name, value)); + } + } + outlineElement.setMetadata(metadata); + } +} From faa9cf856d965967b58c6a7cafb1e85030f95363 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 16 Apr 2020 16:20:53 +0200 Subject: [PATCH 15/31] Added popup menu and fixed NPE --- .../libreoffice/metadata/views/EditorGUI.java | 11 +++++++++++ .../metadata/views/MetadataTableModel.java | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index 5fc0653..fed4c03 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -245,6 +245,17 @@ public class EditorGUI extends JFrame { .addComponent(btnOutlineSave) .addGap(43)) ); + + 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); } diff --git a/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableModel.java b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableModel.java index 66e092e..124ae13 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableModel.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableModel.java @@ -25,7 +25,8 @@ public class MetadataTableModel extends DefaultTableModel { Vector row = (Vector) elements.nextElement(); String name = (String) row.get(0); String value = (String) row.get(1); - if (!name.isEmpty() && !value.isEmpty()) { + + if (name != null && !name.isEmpty() && value != null && !value.isEmpty()) { metadata.add(new MetadataElement(name, value)); } } From c1dc50aeaae0787ed229539e24de5ae8344f12a4 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 16 Apr 2020 22:25:07 +0200 Subject: [PATCH 16/31] Hide annotations --- .../libreoffice/metadata/Document.java | 49 ++++++++++++++++++- .../libreoffice/metadata/views/EditorGUI.java | 9 ++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index d18dd0f..5b65602 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -10,14 +10,22 @@ 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; @@ -25,6 +33,7 @@ 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; @@ -49,6 +58,9 @@ public class Document { 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; @@ -60,6 +72,8 @@ public class Document { getDocumentText(); multiServiceFactory = UnoRuntime.queryInterface(XMultiServiceFactory.class, currentDocument); readMetadataInDocument(); + frame = xDesktop.getCurrentFrame(); + dispatchProvider = UnoRuntime.queryInterface( com.sun.star.frame.XDispatchProvider.class, frame ); } catch (Exception e) { System.out.println("xDesktop inaccessible. Can not proceed."); e.printStackTrace(); @@ -68,7 +82,7 @@ public class Document { } private void getDocumentText() { - XTextDocument textDocument = UnoRuntime.queryInterface(XTextDocument.class,currentDocument); + textDocument = UnoRuntime.queryInterface(XTextDocument.class,currentDocument); text = textDocument.getText(); } @@ -277,4 +291,37 @@ public class Document { 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/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index fed4c03..b1453f4 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -176,9 +176,9 @@ public class EditorGUI extends JFrame { panelStandardMetadata = new JPanel(); tabbedPane.addTab("Метаданные либры", null, panelStandardMetadata, null); tabbedPane.setEnabledAt(0, true); - if (true) { - addMetadataTab(new OutlineElement(null, "Тестовое название")); - } + /* + * if (true) { addMetadataTab(new OutlineElement(null, "Тестовое название")); } + */ for (OutlineElement element : outline) { addMetadataTab(element); } @@ -418,7 +418,10 @@ public class EditorGUI extends JFrame { document.setCustomDocumentProperties(docCustomProps); updateOutlineMetadata(); document.writeOutlineMetadata(); + document.hideAnnotations(); } + + private void updateOutlineMetadata() { for (MetadataTableModel table : tableModels) { table.writeToOutline(); From 26f9f880b5c3f590578aa76d6a02674a8f21abbb Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Fri, 17 Apr 2020 11:30:24 +0200 Subject: [PATCH 17/31] Dispose one open second window --- .../libreoffice/metadata/Document.java | 1 + .../libreoffice/metadata/views/EditorGUI.java | 36 +++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/source/pro/litvinovg/libreoffice/metadata/Document.java b/source/pro/litvinovg/libreoffice/metadata/Document.java index 5b65602..9d920a7 100644 --- a/source/pro/litvinovg/libreoffice/metadata/Document.java +++ b/source/pro/litvinovg/libreoffice/metadata/Document.java @@ -74,6 +74,7 @@ public class Document { 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(); diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index b1453f4..723b6f7 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -58,7 +58,7 @@ public class EditorGUI extends JFrame { private DefaultTableModel docCustomPropsModel; - //GroupLayouts + private static JFrame singleFrame = null; private Map docProps; @@ -80,22 +80,28 @@ public class EditorGUI extends JFrame { } public static void runGUI(Document doc) { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Throwable e) { - e.printStackTrace(); + if (singleFrame != null) { + singleFrame.dispose(); } - EventQueue.invokeLater(new Runnable() { - public void run() { - try { - EditorGUI frame = new EditorGUI(doc); - frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame.setVisible(true); - } catch (Exception e) { - e.printStackTrace(); - } + 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() { From 32cd313260f367757d1a13e709779ef563a4f46a Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Fri, 17 Apr 2020 11:39:08 +0200 Subject: [PATCH 18/31] Added release notes and update xml --- description.xml | 5 ++++- dist/StarterProject.oxt | Bin 15502 -> 0 bytes metadataeditor.update.xml | 12 ++++++++++++ releasenotes.txt | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) delete mode 100644 dist/StarterProject.oxt create mode 100644 metadataeditor.update.xml create mode 100644 releasenotes.txt diff --git a/description.xml b/description.xml index f22fb48..a4f9902 100644 --- a/description.xml +++ b/description.xml @@ -1,10 +1,13 @@ - + MetadataEditor + + + diff --git a/dist/StarterProject.oxt b/dist/StarterProject.oxt deleted file mode 100644 index 1a01ab83a60bbfbc73627968fa25a7ee2a723e69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15502 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 Nq+i2Ej{Q&V{{uMGcaH!7 diff --git a/metadataeditor.update.xml b/metadataeditor.update.xml new file mode 100644 index 0000000..2f00691 --- /dev/null +++ b/metadataeditor.update.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + 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 From 9676a684e2fb396f8e1b2906c1898191ea71858e Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Fri, 17 Apr 2020 11:41:51 +0200 Subject: [PATCH 19/31] Added update xml path to description --- description.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/description.xml b/description.xml index a4f9902..3ddec69 100644 --- a/description.xml +++ b/description.xml @@ -8,6 +8,9 @@ + + + From 0cc1b452613263ea908e0ee955da9f65d794bf9a Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Fri, 17 Apr 2020 11:42:14 +0200 Subject: [PATCH 20/31] Saved --- .unoproject | 2 +- package.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.unoproject b/.unoproject index 67bde5b..1a2dfbc 100644 --- a/.unoproject +++ b/.unoproject @@ -1,5 +1,5 @@ #UNO project configuration file -#Thu Mar 19 15:58:57 CET 2020 +#Fri Apr 10 17:20:27 CEST 2020 project.srcdir=/source regclassname=pro.litvinovg.libreoffice.metadata.RegistrationHandler javaversion=java5 diff --git a/package.properties b/package.properties index e081b50..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, 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 From c48d6fd7a5491fea5eb8da6dd75a97ab29dd5ba3 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Fri, 17 Apr 2020 11:42:58 +0200 Subject: [PATCH 21/31] saved --- .classpath | 6 +++++- .project | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) 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 From a557720a7b5d260ed61a753868a3a3144f022d77 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Fri, 17 Apr 2020 11:44:47 +0200 Subject: [PATCH 22/31] Updates testing --- description.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/description.xml b/description.xml index 3ddec69..744cfd9 100644 --- a/description.xml +++ b/description.xml @@ -1,6 +1,6 @@ - + MetadataEditor From a19a037b52e1d03fc46777d42e4db9cdac8ec571 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Fri, 17 Apr 2020 11:49:08 +0200 Subject: [PATCH 23/31] Check updates --- description.xml | 2 +- metadataeditor.update.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/description.xml b/description.xml index 744cfd9..c5d1875 100644 --- a/description.xml +++ b/description.xml @@ -1,6 +1,6 @@ - + MetadataEditor diff --git a/metadataeditor.update.xml b/metadataeditor.update.xml index 2f00691..f8f1a08 100644 --- a/metadataeditor.update.xml +++ b/metadataeditor.update.xml @@ -2,9 +2,9 @@ - + - + From 7975e49b2363ff88182e930da94b057ec0cb228f Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Mon, 20 Apr 2020 12:55:54 +0200 Subject: [PATCH 24/31] Wrap text in table --- .../libreoffice/metadata/views/EditorGUI.java | 6 +-- .../metadata/views/MetadataCellEditor.java | 50 +++++++++++++++++++ .../metadata/views/MetadataTable.java | 20 ++++++++ .../metadata/views/MetadataTableRenderer.java | 24 +++++++++ 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 source/pro/litvinovg/libreoffice/metadata/views/MetadataCellEditor.java create mode 100644 source/pro/litvinovg/libreoffice/metadata/views/MetadataTable.java create mode 100644 source/pro/litvinovg/libreoffice/metadata/views/MetadataTableRenderer.java diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index 723b6f7..7b00dfb 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -191,8 +191,8 @@ public class EditorGUI extends JFrame { createDocPropsModel(); createCustomDocPropsModel(); - tableDocStandard = new JTable(); - tableDocCustom = new JTable(); + tableDocStandard = new MetadataTable(); + tableDocCustom = new MetadataTable(); configureTableDocStandard(); configureTableDocCustom(); @@ -218,7 +218,7 @@ public class EditorGUI extends JFrame { private void addMetadataTab(OutlineElement element) { JPanel panelOutline = new JPanel(); - JTable tableOutline = new JTable(); + JTable tableOutline = new MetadataTable(); MetadataTableModel outlineTableModel = createOutlineTableModel(element); tableModels.add(outlineTableModel); configureTableOutline(tableOutline, outlineTableModel); 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/MetadataTableRenderer.java b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableRenderer.java new file mode 100644 index 0000000..8fe3ecc --- /dev/null +++ b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableRenderer.java @@ -0,0 +1,24 @@ +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; + } +} From 4152d529f7338f89a33b7f7a9e36adb2d986fb8a Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Mon, 20 Apr 2020 13:54:22 +0200 Subject: [PATCH 25/31] Scrollable tables --- .../libreoffice/metadata/views/EditorGUI.java | 50 ++++++++++++------- .../metadata/views/MetadataTableRenderer.java | 1 - 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index 7b00dfb..8127286 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -46,6 +46,8 @@ 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 @@ -182,9 +184,9 @@ public class EditorGUI extends JFrame { panelStandardMetadata = new JPanel(); tabbedPane.addTab("Метаданные либры", null, panelStandardMetadata, null); tabbedPane.setEnabledAt(0, true); - /* - * if (true) { addMetadataTab(new OutlineElement(null, "Тестовое название")); } - */ + + if (true) { addMetadataTab(new OutlineElement(null, "Тестовое название")); } + for (OutlineElement element : outline) { addMetadataTab(element); } @@ -218,10 +220,8 @@ public class EditorGUI extends JFrame { private void addMetadataTab(OutlineElement element) { JPanel panelOutline = new JPanel(); - JTable tableOutline = new MetadataTable(); MetadataTableModel outlineTableModel = createOutlineTableModel(element); tableModels.add(outlineTableModel); - configureTableOutline(tableOutline, outlineTableModel); JButton btnOutlineSave = new JButton("Сохранить"); btnOutlineSave.addActionListener(new ActionListener() { @@ -230,27 +230,41 @@ public class EditorGUI extends JFrame { } }); + 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(groupLayoutOutlineMetadata.createSequentialGroup() - .addGap(34) - .addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 839, Short.MAX_VALUE) - .addGap(126)) .addGroup(Alignment.TRAILING, groupLayoutOutlineMetadata.createSequentialGroup() - .addContainerGap(748, Short.MAX_VALUE) - .addComponent(btnOutlineSave) - .addGap(134)) + .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(groupLayoutOutlineMetadata.createSequentialGroup() - .addGap(85) - .addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 497, Short.MAX_VALUE) - .addGap(52) - .addComponent(btnOutlineSave) - .addGap(43)) + .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); diff --git a/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableRenderer.java b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableRenderer.java index 8fe3ecc..cde3583 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableRenderer.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/MetadataTableRenderer.java @@ -17,7 +17,6 @@ public class MetadataTableRenderer extends JTextArea implements TableCellRendere public Component getTableCellRendererComponent(JTable table,Object value, boolean isSelected, boolean hasFocus, int row,int column) { - this.setText(value == null ? "" : value.toString()); return this; } From a199cf2734ecb94d445b5e76c54abd5e563a2805 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Mon, 20 Apr 2020 13:56:13 +0200 Subject: [PATCH 26/31] Updated version --- metadataeditor.update.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metadataeditor.update.xml b/metadataeditor.update.xml index f8f1a08..1739354 100644 --- a/metadataeditor.update.xml +++ b/metadataeditor.update.xml @@ -2,9 +2,9 @@ - + - + From 7d66b8d73bc1eea0c5c50c21686d5104a7ae051b Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Mon, 20 Apr 2020 13:56:21 +0200 Subject: [PATCH 27/31] Updated version --- description.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/description.xml b/description.xml index c5d1875..e25d158 100644 --- a/description.xml +++ b/description.xml @@ -1,6 +1,6 @@ - + MetadataEditor From 7d164e10a65d21d2626a4f2ece36c1adc2502285 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Wed, 22 Apr 2020 17:48:52 +0200 Subject: [PATCH 28/31] Modified metadata storage --- .../libreoffice/metadata/MetadataElement.java | 3 --- .../libreoffice/metadata/OutlineElement.java | 22 +++++++++++++------ .../libreoffice/metadata/views/EditorGUI.java | 1 - 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java index 6cd6326..55d5c26 100644 --- a/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/MetadataElement.java @@ -1,7 +1,5 @@ package pro.litvinovg.libreoffice.metadata; -import java.io.Serializable; - public class MetadataElement { private String name; @@ -20,5 +18,4 @@ public class MetadataElement { return value; } - } diff --git a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java index d57f958..a29b722 100644 --- a/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java +++ b/source/pro/litvinovg/libreoffice/metadata/OutlineElement.java @@ -2,6 +2,7 @@ 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; @@ -66,12 +67,15 @@ public class OutlineElement { public void readMetadata(String data) { try { JSONObject json = new JSONObject(data); - Iterator names = json.keys(); - while (names.hasNext()) { - String metaName = names.next(); - String metaValue = (String) json.get(metaName); - metadata.add(new MetadataElement(metaName, metaValue)); - } + 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) { @@ -81,11 +85,15 @@ public class OutlineElement { 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()) { - json.put(element.getName(), element.getValue()); + JSONObject meta = new JSONObject(); + meta.put(element.getName(), element.getValue()); + json.put(i.toString(), meta); + i++; } } return json.toString(); diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index 8127286..99994e6 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -185,7 +185,6 @@ public class EditorGUI extends JFrame { tabbedPane.addTab("Метаданные либры", null, panelStandardMetadata, null); tabbedPane.setEnabledAt(0, true); - if (true) { addMetadataTab(new OutlineElement(null, "Тестовое название")); } for (OutlineElement element : outline) { addMetadataTab(element); From e0302b1652c3d387579e259fed31e175bd717aa3 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 23 Apr 2020 16:44:01 +0200 Subject: [PATCH 29/31] Icons --- images/actionOne_16.png | Bin 501 -> 0 bytes images/actionOne_26.png | Bin 575 -> 0 bytes registry/org/openoffice/Office/Addons.xcu | 9 +++------ .../libreoffice/metadata/resources/clock128.gif | Bin 7713 -> 0 bytes .../libreoffice/metadata/resources/cura.png | Bin 10802 -> 0 bytes .../libreoffice/metadata/resources/eclipse.png | Bin 14781 -> 0 bytes .../libreoffice/metadata/resources/metadata.png | Bin 0 -> 4201 bytes .../libreoffice/metadata/resources/webcam.png | Bin 30877 -> 0 bytes .../libreoffice/metadata/views/EditorGUI.java | 2 +- 9 files changed, 4 insertions(+), 7 deletions(-) delete mode 100644 images/actionOne_16.png delete mode 100644 images/actionOne_26.png delete mode 100644 source/pro/litvinovg/libreoffice/metadata/resources/clock128.gif delete mode 100644 source/pro/litvinovg/libreoffice/metadata/resources/cura.png delete mode 100644 source/pro/litvinovg/libreoffice/metadata/resources/eclipse.png create mode 100644 source/pro/litvinovg/libreoffice/metadata/resources/metadata.png delete mode 100644 source/pro/litvinovg/libreoffice/metadata/resources/webcam.png diff --git a/images/actionOne_16.png b/images/actionOne_16.png deleted file mode 100644 index fb7409d4c25f19f0d5343239c71b76afb20f582e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 501 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPN3mXrY$m5XSwLl@+%#er@=ltB<)VvZPmw~~#C^fMp zHASI3vm`^o-P1Q9MK6_|fq^m7)5S5w;`G(Y=d}+PN*s^B|2Es+6twNc(_iJUYq}5&5v)TUq z@0UIEpa1aWyH+IfBd96!UJxg%nFgvd|^9#!j3#;>;C-djdyMNI3dlc zS3RaondNpZtL~oDk7s>9ikTXkXIJ~ZdnCb~vaIH|yzsq~K=&ry5q9W|6O?#$jwOv* zF>Q*i-`u}D{wO|cPRx^^Z*a=UwMuqgBj1};)%8L>QM%l7*IJ(0`*rJ)NBm1JWy*+# p?UFIQx!WPZ?8Ro;Kkwr!7!z_zWi=Yt0Aq`R!PC{xWt~$(69B0+$~6E0 diff --git a/images/actionOne_26.png b/images/actionOne_26.png deleted file mode 100644 index 268a5281b79b042820a5048c3784d5846268fd4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 575 zcmV-F0>J%=P)WFU8GbZ8()Nlj2>E@cM*00E;(L_t(Y$L*HQE5mUd z$6r6jCbbZekb_B>mFI&KQI1MEcuriEi|_}Glbrp^K^`Iw&d$Qh`pwg9IbgAQ%2V|F zO@1!6u#wH$X`j>g;obMu=iU4J?JKCNsuG2YBT5wm#X$bj{Inr^U&%L%ys0WDqy6X- zf=lg}x2)|SvvzQd#pMPBWb@$PK`VPsZeL^omTe9?D~f~aOp~*pWgb`$Kv+x zj|UWGq%u}t&CXzZ=++&0ZrC`vpeiSmI6+|Z)Xkpzn$oQF0If9C6@D0e-E>!$Fi=|- z&|ySU_o8^2+c_jj6Hl9|kXECCv?ML_Ry)s%H*%mQn}d5qyonh6h@dj(AkOG#c^(AON{3dKwIQ ztUFIxl#b}DHUgj>nF`Q;Uh_Rie(S^_A^2XsAA8~4DIxY}h=HOGdItrpm9JgiD)#^Y N002ovPDHLkV1m#N_|pIY diff --git a/registry/org/openoffice/Office/Addons.xcu b/registry/org/openoffice/Office/Addons.xcu index ebf48dc..b9d93f3 100644 --- a/registry/org/openoffice/Office/Addons.xcu +++ b/registry/org/openoffice/Office/Addons.xcu @@ -1,4 +1,4 @@ - + @@ -9,11 +9,8 @@ service:pro.litvinovg.libreoffice.MetadataEditor?openGUI - - vnd.sun.star.extension://pro.litvinovg.libreoffice.metadata/images/actionOne_16.png - - - vnd.sun.star.extension://pro.litvinovg.libreoffice.metadata/images/actionOne_26.png + + vnd.sun.star.extension://pro.litvinovg.libreoffice.metadata/images/metadata.png diff --git a/source/pro/litvinovg/libreoffice/metadata/resources/clock128.gif b/source/pro/litvinovg/libreoffice/metadata/resources/clock128.gif deleted file mode 100644 index 73d35051ab1d3dddf01d594f196133d8c3bd6492..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7713 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 OF-Z38`du0TZ2LcWxBlt? diff --git a/source/pro/litvinovg/libreoffice/metadata/resources/cura.png b/source/pro/litvinovg/libreoffice/metadata/resources/cura.png deleted file mode 100644 index c311b868ee70bf3007682dcf3c3f7314e78e45f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10802 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 literal 0 HcmV?d00001 diff --git a/source/pro/litvinovg/libreoffice/metadata/resources/webcam.png b/source/pro/litvinovg/libreoffice/metadata/resources/webcam.png deleted file mode 100644 index 4fdb98fab77685bd5595fa9182356e04827a2721..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30877 zcmZsDc|6qL_rER5u1%3$B%wmWFd<2lHe{PgwuEG#v5h5BvhT`h5!uVW3}cP4O_6

2R>}vC`4eap+#ZdY6ul z0sNPN?jSSx=QrZ#E*%}hTKB5PeZlVQ&}DBGD{x7+ z)5b2{W2n;0{L<6Xo^Q*Z1IfNw391W4Zdv9=Wvw=Lr+jlg2P)Zo_f)CdRL_AFp;Jb) zIuty1W*AE9r^r#!Dz%j)tenS#!D4c{z+4K8h0#+eH8p~aU4P&Ht(H*cVnRkm%}_@* zBJ-Z>Sd{HRjm;|GT+cP?pEPUW@@FSDp06pK9^Q=g6hKS__PYxv*rk-NrgfbwOOL#pyWo~d@T$Yk<^|*g zis8-3yo3phs_D93l_hif^b@{QMJ~l@Mwuv5N7MKtnmAWXrmetxU$(fC@3Xc-6Md+W&7>zcoVEI#&u=7 zSd{AL47IB2*Huh19?ca!*RFr#&5~t`6E+z`Mrw7KsF;TCqLuIIDEVVbpo<>AD`R0fU55K7CAZ0 z7n(qNql8R&Q25l<`XKt0;KnjZ|LJ(PzUORhw&S^P@`wqG1pVhboBoqRS=5K|8Kns% z%Q{8_4~Tbyf$`kNl*yHCyz0`30i`u}z}q8EOlysyUAk@JY+L@wqxBWKSr!EI>`S(T zev)*tD2QqI2W$W2Gi!DC*j5wnEah`btB$xOIL}eWP7NNlp^Pwy$gKt8tZF|E%i22y z-8CzGa{*c>&%LUGE1+LJ6tFgR9Y?L>Xee}5f8AP14_S+!>g4;eR~9t?dd88txZZN6 z_Gy9R=Z9T-eET)0kb(UT5b15W0S7a`Qo)n00Jx=pK$aD{BH&A@IDJJ|e^79lv9<6o z$2A31Zp^}m#VI*dB7hDX#q5k{M zV|c;ugA?|zbo3SzhmKUppIpi*P8op;Ypszd)7mF$mE-CiRTa|s<(*D=vCZ-$_~x{4 zcyfGa68_mQA9PTc;rsD44s;^IP(FFQ!g1tOXo8#8iwWH1`ZBf6X=HKbmCj`=za{BZDl4zD9g{K3)cE2M$ zQJjva_V~W;5jy1=*7cb{UU&5HH}Q(R5za|>}VvF@2r_JgH;)j3!WSltN z`)DZQ$+V&M@2d6g%5`%AYesY`(!CsqbKmMTXxXe0+TewRASugZpe<;cGg-O3zd9Mb z_{LZe!#Eg_OB2%EMK6PtjoZr6$-zhPIF4xxaX--4&rgWFL}@TK!^6&4KWqMz(R9Ro)6?nb4qs^Sahne3&{>Qk1^q*31RQ z@DPM{l^a=q{rXpflZjsH#p5+(!yk9O&#)2b&@qVLvPnH{`O@W*>R|{vK>`=r65;Tz zg*xb_UY$VVbfv?$VqB#+rsvshJ9*=#rn%vD!Q}cL8RxMtV_s-|JNV2Dm4iShh=6Xe z%BKk3$|%+w=kMS43X`KvX#U0agVhx!L3Ee?WUx6StzE=MTYks*+e;E!dFR4*7+_xr ztJ^D3u(O>r%jkw8yY9ibXhy_@qW$8-3o>32panPL(L4$p&ZPamxZZ))d4_4LK5l-= zl*w(aF3xR@ySh_3m~>={4M87|`V2o5K!8j>2I44dv!^#JHW7S#k1UxtglMhV4zBtD z-`}ekUP-^s3P~aI;`i3kbO+@kj}}lq{urDfO&!y>dV#)am&?;p&nR~gBJK49Sb``l zuwS1P%9geN0x7dEhqG4DRt1 z);Tc9X+BOmLI+RLB_!$FreA@95J%822Jhn#|lwsltd3bE5EBf(+D6G)TBexq2r=g8_! zp|jQpLBE$>%m%w!Ma6|)wk|20(%Xtb%7}^Vz!u-dlCSu;$v@TE!61hWFg|h;bdzHQ zAyI3V{L^?g-~cQr*{u%+pP5#EJXi~&h9){ewS{Wp(YeWABs67MsidTZL zdzlDAR#mmva*h%_!6t~vne|%*VQoH5r3u=&0or!w;zN`|u5TUGq)b?t5|R=TY-+Vf z>v-KqN;hBk?$4LmffoVP?gpj)$gh0Iv^Ly;~&l@#37$BVa* zKs}e0&|Evf1=(L?l|R{!#yP^9plb|Ue}1;H%K9Or{b!w8FqQ4`Y5NZOFci&RffmX< z?We){5q=QFf~H3pd1~Qa*HeRcSOf{q&tRX@YWnS`Z;8=c-n(l#y`lp-z?Eio z8*P_>wfl5F=rm&DWTc%9Wu`mw^30}uQWJ?fr?_!-u;d?$2c+osDvC6+cnK?Do|Kc*ic^a7FNKnmSW zpu666B=VY_gDK@BB=os(MIdNW8_vA{%w5Gn3)1_E+`QqBk)&$~7YoUyK6Wp=mQETT zKpuPwfDY^)GV9_%d6AVMrv{`qg4`I=G9iJKL0h8ef%Nc0S3VcoG4aGQy^~Qf(<2(}2tbkHJhZl$x?>!V(z;G|q;sb$wj2?V zm7ud6d%7RWdNL@P?&^o)(ndGnP6dq0=<7Kk;K*Obf7?&Dx~6$*s@N7WHR=O`(6$7X zTSWD-3=$U5)%S`lpTfzhx?#+uv{uI`_ZWm(uF#0ZS37x!U?t-8VQZzo3{vTy?^&Ea zn3j(r7Y{s@RoyW7tMLFND`9WQ-fmA+Jr^x0K^Ft_lf_6~Ez;p8_8-J2B-CAY?7;pt z>%=MLyb+~OWzRLj@Hw;Ed!;W7z`@m|@Wo=&1e)L^RQLq5AYwwQZjbU^!B%0a_zCjP zO{r~u29iVQ+!q%ybE6gP!D}?kc^6`;xVGkQ%Q{v30@-;Cs$!PiOBorEjv{KGX8?MS zpGa#b_@6Cyy~mSYir1QZtU>Wykz^7Bt24L>$%=Rrgy155EDlBt3mJom!Gh*P{%&|K z2zdei9LyVk0A-y1EA$}~m`rxa+!uN1+Sey1rql>rFuL+x%Tg$S(^))Y+qa~9gw_R# zECvN+Cw;G_4HhtRNz+FUhMhhZ+TRNeH`@0;Gzig}-x)JLW|YY`RiiTV$JLiH5X-+o zgNFW$o+-^dREbR*8o1o#W4PYbP4(wJ^h(pNd?}`u+*BFxXCn4#Ug~kA@zNuM51M>> zTcJM-nXb5^pDCzR+aL^!S;()jL^+K$IxvOb4XSZCbLQvK%U#Jzef4ps4N$T_*cn+i_A^IYl~++f46C1K)@Zt>xIMqo-k z7gpuFb9z0(wq?4)xrb($>WnkLUyG%?`o1{0eOmIH+rNZ@cr6zIHI3($+A-Is)AUml z3yT(~bNVr;QA;fUYQ+tqS^V_c!1|g__}bM_VC%`{X4LnZFNA>w{aSk1p8gVR^b*d* zMcc7*h|AJVi_T1}yzn`QQAxct`y7&pw_7v;%3N73NecyCs&Wpd*L zHCmxzkSf+bOS>{rL;&y)6E4H{`p=;ZUEx~}9O>fp2Sdog_-V;j_+LWSWJ_K7Rk5xQxl`1!+1*@|EqttqptdQty{{70kWrJaxIhrGy6&?ZBzkfVoP2{lBgVi zCe65-grNb>=kkmbTp@^GZ-v)$@-2ogFLj*M_XH~7!dz=RVCOm)WxE*_1QkYEtRqN; z4c0V+tJ~;u8yGN{$2ZyW)u~v8-I46GmaROin#zG{7vN|3Z6(okj zdQsmOzY#$J+yCn~13|pK!3jE{1M!lHlL0LN`Yw96@nakds>a28+J+xIMt8E`-xQd zf2p9382Ra|yfDgy$i;hWk7L7h7mjdw{%lj|w6fWWwB?zs5%kWx#x}oT9KZ+@fxHi3 zmMYtwiH96{Td^jXgYPYF(fQi2I)Pw&RAqRN3)fXUW@&?M`b%GIoU8gOKCYS!8`3+U zb^i;2Y|ZsS9h(2uRJL%WZD>*qi~P{o%p}|~oKL+iqQwmmbnE!G0f>&}Bj3pUaYty1 zlN+!*aGsiZfmfaAunmg`#`FIjFCA%b{hqDW)+1M1pqeOU$JRn$hFwnJFIer)AE|d*TG2pu;B*75^ zkA3l>C*%F^kxxdhFBIOYYAoPSiFin|hUGp~a#lIg<;MOlY5rYumPs zdzB=4c)KTRdXLV)1%%OvpePLSpHRl1{I>0(vs{NYQ88=XVVe`w2w zf1OVh6&afOwef;-J)1aQO)lkrJ|ghv3VgLvQOMDx{3zbSRNovqth>4Er8~nv-=y|Y z=o=g2vh)=haCFB%r|oO9`V3d zc9-3}qPxA)MYVkyLO?&cv3Yh+0Rk6^C8B&4w{sN?h9TN=h|lO1z1;Y&KHaL)ig`8V zmf_v5lktdh<~0=jyamCzMnefg&&I53s>dHByGAVklP3xXQ1r>A zTmqh?Eo|>BNu%Uc91ekLGnR;XA+Mu&y0L1=+jZBGXRs2Q?pyIh206KW+IlP8IojUs zc=XSXEL=3svmrzObdAm}(a{$XVrhaxH}x51niT5vRoHKxj^Y&1^JY)KG9`1bwa(?F zxbnXJMbbRUdNxR@71PffR}MAR?t40<;mXPx7u$W&DNXIRg?5fH_LjN);S12$p0}eT z%vec2D}-`@h2Phrd9GeR98mTm9xFq^102dI5f_LkX7=tX!`_A$nv#^(j7#BYh+d!L zpf=3g>tu?8kGkc(Ebps=JZbWSCg(S$v!lNSJPKj8bUwU^9 z4L>fZ9#Y88Mc6}TLt_vCM9!GJM4kUa*8UINaV`Hd;mgI?UhcEV_?)5d;dM*)XK&2V zO`*g69h79DYszO@yYdx2lbinox6~yQ@%o5X01}$4FVaO}7Yav7gK|dO(o$6B+8H6` zTQG~Fpx4Rjd&C64cQ&JUG4#_HuWv1e~u zZ@I_o1Iz|Lo<4Ntd7(C{n@MEbwXba;va;#!V@Uork)2NOutYhtyLRZNH2<{-4jkmI&Q<0hgy_{atWw zPF`Dx61c5@sUIs{=X#FwsT`8A}5t&+_ca&f1Q|Jw***EG)XH5$I z?vHzO_d&k?t7GdP5@mZ%|sOC9>W9N@JhR=$AF(oe} zO0BB$Ca$!kQy;Mj5rj^`k|e)HCykq}=$4sUFA7sr7Yx}hjJr313vSiMpl-ehsuhme z6$-^=2*G9??%_gM?ZR78(~*7|+Y9iUc4yp;*(%ms+A-@`hv+|bZG;m${_%)_5ECn_v6=K7%p6sI;tWdnue{v+SGThl5Bq!B48rv# zINDIX4e#301>N?3OFR1%D2O<0ZgiuOfp6u`ay}Ui*o|X(>C?sC0q5BG73e%Czc=b| zoc2+2Dz0g0j9V^<@<$5^K;a>lEW5z^-|Hf*N`rZ zvAFP6->VBx7K4qH-chV;=dRm#z@3O)pX5EPj!ZdU4ErDXjlP?6mx~SyHd=SD1!1|+ zBD{^;mjd#U*2h2r~vYIwvOL>;4^n$B(JB zSlX0Zt~q$+3aPcLov6o5w7P(B6KL-7ZBfnj@ZcNN<;QGS7r9o%S5EGqM=2t22$x&T z5u=X!f>g)f@xpuYEivUK_EQ!Gi2Bkn4y>+uXyUC9_R;8Zyz*vrt~%0vaduC-|3INA z0j-#ffUhwl&J ztho4dZ(oseYwj_aq#bMi_e}n0JyOqhny!_x)tW=NPI^AGDP``}jY5?s7FR{VsGG>x zQ_7yA6WYNe+H==`jPN95O{WG2Y*cc?_?P?n)WLjm>`3?%hfy1q`m^v8^@TXX2chBpR8gv&0eXg!V%^G(ftLvCPPe|dl4OKkSZhn84`Vqy zH&_vPO@%GXK8wK~BCnFxRnRig&y3&ixZOQ*?ob8UhdrI{WRTZQSh?kN>!h5)0nDR^ z0C#h9DKt#O%e!wAlQuqn>Pk_~YgrDNAHiPOQLJmfA-t)x&2pcTg+D&oCIm^xpv5F& zr|no7_Xe^HBJX1$^y^pHAkrI!ua;mu(b!ret+8j%_~coG;ry5d{P@AoT*PT~iKZV~WDlBh1)c$fH|mc*CtrC8EbE0Fr_^$W5`5ns2ZUBA^@?i*v$ zwbZQFPu`&`)wlZ&gAEB-`=!hic#hXRsrn>sq@MXDUhgFAcr~@;9Q8=tP-x{+2lT>@ zVaJ=nafdW&X8J<;Ng{*XJItr_0IUPzLhpPWEoiS~7xtkYLM^xb~ims_VKrhX^Bn#1gWy`4vxqShj((Kuj zP1f4KK_@E`o(&OJE3%76I8|1(y?0a*Cj z5Z4V67A%CPqL?AkR!s17{9H-#M-O4@KWinqz4_d=WmL;G>6Tp5Bi$-t)N`481}a?zR{QMW6o?C8VOm|giS~__{{b;(+}6&EuQpi;yp$Lyai`a5x@HJzg=SI zagArggXk0F1w!wN880_!Rr<32BbH>K;G>g2zIwfzc>J)7^>g;tslbSx59;W~Zyvpm z|H~KNkQbwb`)~%s{V=Z%e8e^Hf<#j8&pt)(MIjK&qUqoWC_dV7=pP@UaT9&`D)Z`vrSOQ*RhjM^oSTUt>f>I-FI&EZyZ{d-AA&PAo46?X}~ zD=fEmzy71@?Z|Xl_Er=6shIjOxwBIyDX1Ssb$sVSg?i&%u_E5l0L|K76rkxdw|$&1 zTKbcV{G0}CBKwt+|20pV4hkg;mSRBH>E*Nr_ns%pf5s)>LFb|> ziQ||>I>HQB;rMl;uxdOxd+s5zx?sQ6S@k@@^PaP-nLd~6hSq57O)mAea#=zqOI5U) zpm+Sp?sa2VAAK*^tZd%OTr0S%K@tNY0@|2Q!1P%(OAsknb?`>W+}LBQK%6FZNjX!>gD9ynPQj}?qM z=m`)z*zBp^6;l~AiigK$26e!_mCA?lBo}UPBHxbmCBi?>!5nh=LydA<}QQ>csT?&nN)C@mQoKPStX(#RDLFpoH1mh1ocxqac8 zBcF@11(A#Oth9)Bv5=1M9iCNpm1;p^e`~1AK#Di;f@>pgp|Na=y+!FUwOCgHf}G8| zD8&k|LEyY6!atl3bGP&cCV7vqAkY8)u%DvA4GiSX0ba zPS&$#B)+NeSBSZbDWXQbGQZ?^;;MH`Q>VPAxZb{ zy?c^-c>%9B?84lxLBYXV@3Ogo4JI2>EZZ&)-e)&D1}+Jb$C~GC-)9axYU4CNAK4xA!&j^ z<@qGhm}C?tKfk1NB5z?bp+?ELj4XXNS9d#O{Y3)w7}W`5&L{=aYUyRwQ{FLZeU2cy_+ipg{vBso z3!Cet9O<01raSNLoaoB;aSpm_^Yi-cn`8~h6>0Wvg=9pZhmhT;|)#vCx z)$sgQ=*;>URz1DTH?%&76Sj`IKS<27F`6$%iQ&=0?7Gr7HuzNH5*cRm~j_}1@w9=u*7OS8v{EKP4lI8ZuwG(d{>Y=tW_3FFD5TBjxT_zI2$S zYvN5IuM+)tv0dh<#^v~Lx9T1mvJ|$CMOB1%;bKu*e!+Imr96c3NM|pv*&x}) zhihmw^+`Am?kI;XH{TpzjmB*S_>Se+Y;eQxH@FQSdEsDAnLhDG^|+)cm4`q*uk?1rySdmuzm;md?IkhS#asTFY_AG8_wK#({R!FM zYXzUQk6esg((t`=2ybsU=kNd|5$&;-Fg+@pTqHNB^^4oFGHcRq2vl z!x3BCMHq$aqLy63Oz%7Le0p(XOKAnUIZ?qWaREz%6!Aa}KYMxl---ZdHKFV@ay+6S z<{z~n`}Yj7?QK6Fe#r^2Th-w^D{YOVHf4hw_QRrr8H4ogo=57Y2~Z~#k|d)|Fc=Oh zPs;JX$)Z+D)PGM_IbkRbyW)F?9u!cd70>)?7o3H{_N*SQ1?OI#U;g5>qs2`IcG|Vpd zp*}~8gdMt)Ve~|(I$vLoCU(K~5-t|oJ|pqkrYLfTnw<5#pl`-t`29!8qcKpw@h(4P z>I1QE=im3IW?M?~@MgvauhIoy?R;QB%ZD##@{q#4Rza3z>m0y5B+Qyt|0 z6xfYskl-@Y8j{0mQXW#iG?cYEOxd2-qLh$|>CT@ZX076(?)T*#u0Adj-QGy_TRS(E zz>2UjdYW^5Vd~&b{eQ1y-NgkRq=X}df(?qRrpq>k@u(pqO+0#sM0N3pM>5E(R)NHM{1Bdtug5?=lIfc}}`&UYfYh zSuPt~Iy!62YKLjxX;be+!F(?zqEt&KQW~5G&y~*JjEaGpUxMa zPurVa9~*W4-pyB8_m(xIn``=uiv-ppv^=4!bek{MSX*5jDWKmhXODQ@1`cz>U zF#RZfpBwjZqDoIv$znkULK>L6^s6K8E4S3pIk`Bl>9S(A3l9?JdRHjsM$c4T$?>(f zHW!tGMt0XeRsr+I`oCk7l9h6HAtlADkkyYrxH&zulcH(jAOSI?x8t~qxtrVqclQh- z8xk!~89hD9oJ+*K*vPUzP+p$sm%~r$@x&`W-CxwDJbJUeFf4NxwY%*syMI3pH|3L_ z7gJ;Vf!GNY^$B^Yi-D9&XuRxXeu+7^AB{z-@AzXSj!($cwZ$z&r4ed{kKZD1h~)zN~8W;VC>i zyUv@YCxS}wJwa*5H9s^=)G?N9uPl0RmhoGZy63}jF`jH+O{$l*UIuiJBvgIOw7=x5 zCjxSnp^-RKc@1f&s-nZ(h4BQF%Kd2U4Rv<4_lIbc8J!$0dg`#dp>NDa%v#>^9OXET z`nq3x528$*!M(#_D@xv;m%67wP5zY@W!w&vzq9VkI+aiaN$UGkb1y}m$O3FGnxx?3 zt9?$LFN@RrL&%?usn=q$t<{BQP*=hZE}%Uftz2h<{@KhIBjv{13OjGINx2th%t}1v zxdJua{FL!m82PztN$g=63#iXIhcBkP{enC{?jdvuwn0o%-&6WPZuayt7b>#tDGR`% zoNv)r7WzP4eH`U1AQB78zL=#0afX1JHqK)sL61V4)`&@Ehsu;QGDT!NP_Zi-bUGEdIJfZ8epiJ!2Nslh& zFOL=Q*@|2C*@`KJJDv_tJSTb5Z7%L9V;nAGTd}KlK2R3jm{6h)gHa!bU`7vY}d$n9(N)ZZspNt`rAos|v>a4X>Lf+sGJ#Bh%_DhG4wZqNJ0a@oSmT15;Y%Y@&hO67& zsvm4xi?lzoD6h9;ZzJllDFuCxS|zU8C)2TKwSAQqUV}ci*!1dtZXbM(_#{jN-LPgN zRs&E#{w7e|Y#qPHJkYgN|Ijefcxy}FBsT?WQmngS>{@b#!+Nv`Q$4i(ql9d4R_;`u zC#t&%pA`mMpc+@deD5n++vxA`A%-$wcxXig>Yp~0O_y^}+{o2SbfDZ=k-QY;{++TMN7&oj3!0V6^em>BwJG4{K&$!8wG!0j8T3&`IuK zm44q7+r{F-$GbNoS9C-35++B-?ZRxq@JmU&I2FykM;07lZ$aKCWE51 zohjYx!wt15SlX6lI!})cmqM-cxmUSHSsoivN^bhhYMbah?wR#}a(*h|5o8uZC|nDj zJVGbQoa>6I3R*5IyBMMWCVzgoqU4gAbw2wlTJ}&Xh%VVFZZ^2_I68>x;q@C*=mhCd z@-fPJ-{VFR^*N^sS6T&4%u<*m@jrh%jf^*K2Id``8XZ)J6%(=dInL`PlGP+7x`aXy zpSbas(>cPZ5GZ?khy{q#kvip~xWTsg%idLBvM>iWVe8S07*%~g1!>gK<3obEKmP50E{_nf-X8?LT!5-p zV-#-v=|9$S1#|b6-3%pHo1}N+4_)v^zEI{!8yQ?zPDL4s#T6&a|9Eeu=*OQVK^I+m z5o5-uOIPArc6Hm*3h3I6CBT3VM5Re(#P;L+f74icy%&B|vaj&dc6!q;s%@z4CxA{j z$G_D?ByrO=%ruIw#Qn>CkSHx87>pb5wjBlV2Jw5nn0e+OT$kL)IS~*knLg|2#8Xfpr>ZDKZM%ezWBVc6oO$%Ag2fXG!|x zB(POS@ohgJU!}wZ;Q=20Kc2i%r;Z?6Z|*GZOjm9>Czd8i*)N=`O9 z9LU7Cl#+8KpThx5)-+{tN-zEl_^)#9S?KEJs*bLBngzHmJ&_tG)r?%x(5~5<&=qG6oJ693*{vSp_EE-H z^M_2z&##ud_$kPshK!s?L>7hfcjHL3_|s+mMfogBU+_;Z%QTMqX*yt#gJxNeWn7ib zQp%PG3rW(IK2_pZXo147|4*QJ8%*Tv&S@Wy1aYDe5@%Kz9=w?7 z!Z$fOVVz5!m9!e)O_mK$-#tUIMLOZdx{asa@4{zi#@E08%*`14`6^X0y%t!cFzp_! zMPWsqpoD(`PQAVQHtd{(qTAH3c@Tt4_9Y6qtVcC5s;W&6{up+?Bq==#`eOhuUK8xg zT*uT!k-z+8#2*BOf*6B%V9KrCUjMcXx_OF;1_$spLOob9fyAWnt=%PK=5Wlxj)e`>DC#U3Si0K@uXEs&s zAlOJj)cPP7(Riov{(}@*uzuo`zFIL54~O!r0kUb{8jf6#_J~G$c|1~-Lk(S88IaVY z@V>PPGk&#kSXGm@;?RUWF>rUnvn+3F4< zS99=hhgbf1TdeS;Oco%tWMg#ViTr=}w-TzelhGg8S7?5TD0{!sMy=;mTtYq)TuxAh z8Z=2IV?lx|MqrxEWxx+Yd+v9XL{3H<2Lo(CijFK zV3bGIpDesup>>$yq0OHms z_=Nzhs=7V5s7XP~1lG7*efADXG2eHv!F(t7yAn`eYta?9TRJpz_~LeeFaCe9Wpf}q z6V@u#z=@c^07uVev@h>-oR*<8P!QLFmMoK;~Fg3@TK^_O6kU?Bc=YDo`2# zkX<={Ns=#?x*3EQ%lPvwDFRTh?*a@8-1u4A-hHSPvl;I@m2%09m$D-^&oYkED_5bw1GdhCTlFU+Q0C{61gm&LFPRjcp zLc6g@9w#Q@ssu-wKC>C;Bk8(^_Ny>ZS5b(vw=Dz2(e9>6M zHVjlCYH-l2t(>NMXx`5-%J0?oi_<6omm!5uW~7UP_|;B+=?`14ipCDCtf~@HqZouy zs}S!+s=u5L<;fk&dZHAOuv#Eo5Esf*c)xD=yvU>o@bdo&bF&{xH@(zdZan2V%ffDC zg9N;@m}4W4i`DmDJtfGMjjN>|Bq_yggN(ZSX%G*J;V^L@|9Dyn>63z7@ZRdc^PM;M zWvTptMVeup&gRS-v&8fBHCZl+sm#TYrc$yp-+)AFkf*aV%^UQCxz1%?b*Lz%c8WqH$IZaRl`qKAd%nMr#HybPDu#_xnN!ngzBYWMANVLeL1ElHOyK3cj1a9@&g=}F@g z+be3i4DWPFJwizl7B6U0i8X_riP(yOXMN$$^EW7>t2|H7RL;DYjYe6mBEPU9!}v2* zNj;agd%Xy_bgJKIj9-}X*@?8ahsKYuP$(NT_w9G0Jfgh;q;%%|pM1%>YvMLD{=o1` zjpG5IGyVrFQ+Ndk)b_31J=HjtUG?{%09~fE8Vx)dv=Furu1Bnh7Wsj}su(OR@}Q^P z*Hg^7Du~~oyJy?R-Bcd>FJG9he!UGd#qVZs8HhBH0N|VzoB=@+C>?gpP!K?gTe8TvqKErSC8B}^C@N{qV zpb0Y6-QpHnqE)(dvkK(DCqrFKD#QPr0|PD*-i3u!5O=zGlX!aQie+cyWO#jhf}{Ah zQ>cs)Hn(p=sHnWW!y{9XV$q+8jJWy_C#A%I5MO z(xN@EEVNQQy@h4*4n+w%5&>zFn5XRdxppytM0V%?+XFNKlzt14HGY9r3?H=*g`)G|7>+q3aLp2OhARVVJx-(t+hC_tfzQ{0ONdSoc zx7QbZ<0y`CU5i5uAO)uZAPGa-{bHdgK{M47a7LFQUTqx|fY^IWN=lLy1r)KuQH#46&Q(n!obTuyE~(kdCV3 zNXv=5vnrxHJ;pXdfu?uw-tZQWkdG&S!muR2Cny1+Bt{*!@8#?>40gDmgAOXq-$?TZAe+!GdY_U*jPET8#=M5v6ly8&<4T)zLu*7U?L z1^M}LGE}x+Lti5KGOfZzdtRh)_CFKwrNLY~a*L=7JH3s$$>}#_ncp4X?e67gm!mou z9>HYkHOxHHlmSdu=+A_a-k0_z{@567)QrO=98h96Df9OBVX2|J3I>uYYJQ zA!>9NSti9ty70QtkNR6!8kF2_!wp98kymNMee-*-@!x5Ai71Hs&_D{USZRp4q$sR? z=dq1q>o)@!Hb&5rn%!?j057U=qiM=`z97{pZ=d4}qsM#VM%t8i$GwuheR6oldS9N# zE)L=2u0yV-&q+p}e@a!1`Kmhi&XMF(MiCeY+xc(_9Z_nZFB|#&pKk|`jU9Ixs3-tK zgNt4VS8LyAoB=+RTz~JF^TG%(qbO?kbKcaX9Ljq$y_{oR+Xi^5Jv=S) zDM+AVdi%zMpdt-?bT`|nM9nMwUfi^@_^zBAgX^c?v)zW#yoj8Mn$o47fYx!hO=`ml zP&--Q*(N->O;OsZ@d3}aerZyY4%2O&28Gu3v+y^3$DGM`J1sRzyZPT7!J3jd=R#IXZ zRPRmWb)5HA(+UDwshXeORLpW}``!@&uR*Gh5&LZqWc>QrW5Q4C*lYmR;M=K_+5(aF&7k3U6%inx0#JeZjE*28L02UPvrb7A{cj->E< zuX#Iu+Mv(Nt!GjLaM;>kN2SWPwIH{pXped|Xq|Y?EG3Lz)fe7E``DtoZ~K~-k((#p zY$YZAp{2aJWT#R0CzFtQZ2ih7jC_hY524VK)H9wmT+t5>W_zx$w3sk4E5E3S&+b3~ zufo_n7yFEi426e8ua(gNz=avhX5ZpaYad@7MVTf*_uX7ng_*IhxLAjZuYsXFi5<$s zU*Eq1BcPw5RjZW|zuUn~KjbAJ?L7Gc^oM;_d|!A=F0uKqmulS$>es6TzJtunw+Ump zD724%y~$Y+1cyr;pf3d;zQBM-$9M(dl)S+TwTB=jBe(ZZa4IkrX*3HjAs62I|G2*0 zOoXf~cp?}M3J-e*2d+{cnU#>`TiE~?>3D59s#cKHhAw(9DuX_SXJY8@l=*H;84 z7oet~@1H6PU|e}1%@{;cU)A>8hNDFgMF{y>EZ=QXb^DF$E@d<-6U6SgUEllv;gtIb zL1Dy_re6+eoMH8aMPf?nf||0I8QgOCoH#Z)tf%tkM6}jYoB6F!FD?so1>n+M+td-q zX%fA6$4S{WAKc5XsQ>$G=TDox(X#y2hl1hzm{&>{uYbBqb`5sc);@Of(rLDfOoh4- zQ;VXC3URQqC6iFZJ9>0uS3!RYS?nLrKl264G{I~Ai_F+d2pb1pmfvNIl^;ZjJ5Bnn z+z>2azkG^maMPwwz*et`OQr5#o(g0}Jmr6rA@*NM=*=Ro*s<>S<(|MI@gRvVR`9Ws zo~^bdP1y&{eo9^de0M^+aQt&N;pcoq0HCk>8Wug{qlt5Gc|iM)MH=Av{>QUvcSEK? zs%t-BU=s2`x~BW~BzqXS`JsPpMZ9<BQj?+1|z3IML5pNOa<_d@#<<4NeRO)OFZTr5`#OwB0UE{c$f?6xD*31Ejeo z@Uo`GA=XaZd%>B08Y?tIy78(_5?$Ne*$(`M#+(YL(VRfV!eYyBB zpz3~e17EUfvy-44Cn^PyPn$7#Jz8^!GbT;K8BAp#@O4C`t7yG2NTaV@c&#I?AqWVl zkBMG0tKwZL`#=G$ZVv{XqOpO5RVmi^X3qMF{%4gFT(iitc?V{0bj^#p6KyfBWz*(wD?rAbQO-9P(7nM56d+Db=Q=nAtF!LD zRJglQ4rtC_f3yYCn1RL->yINsKeiYgFr=(Zv%GZsi^l!d)3f%@pE6^O=PlaXP66=X zSYN_v<4I~VlY$4m$o|H*ae-J`=<65ehFuQOGa;BN>*g65e~mb5(t)PU4)7fgj*Z7l zg{{|j(tZ%+r1n?6V&0vp@r-N)g%s;<^+NC7cEFmYhjpz4Hf)@>CU+pCOK%{5=TO_@ z>=R8-p22J=TgN{$E{Z z9th?7_HjZ=mL$nel7xgJ4BC(_9VN*!ijpNx_7Nr=A+qn2QQ1x^LP&-o`#MDtV`psH zW=6~~X5M>7ztgGC`)7IPe(q@c8pKLC3$(Kl**%RV>(A((w-sYzt}7u zH5EXa32WBg|JghIZ9qN8{KZ!i^X2H)93I=x3Hhy!@7_HD-xhZ&0#f=XuanLPP7v3O z616*INgR=o&W(BUDeSGYZws~a%UnJm7~3AJJ^8O;_vUmG_RCJ-^cXX*iPt-N`CZ5% zxNOnrjFPDd4CHxWD?aob@oBKtw;*BPaOwtmHE3ouT~Lan6bS@~Nt*o6*O`RWbZm+v zAuxHR0>{!<7%NmE!>;lOk(s56rA}#so?EATPfu|Pr5g0Q4Shb)nweiYm_wOJr5hRK zIvj-ZxF*~{tG^7tU7F4Hn#d;Y*w!3Hq)QiHgSVeMP#odz413>);2rikh}zkL7^1`H z2X}H#mo!NMw~3r|ZdA#!5wE5R`_0nr3Fu$IFWoyp*0nl`G?HmFO$9Cz6{JG^$?{ju zyksM2)%6WqW#v1nlZuJ@MI?)t*fVoq=R)7*O&B6KI_{d4*g>WcT|j?USu|p}7+7(7 zQgOH%q#FNpC-Cr=g!U#(vptAIw*XIY1u*@z%2}<8R9>_a_98?3x%Y}lUz)BtZ_LsW z2j}wxDI_i5OF~AkLuBFlU02MGZ`|!r69u`((j~!j)bV#(KnnW9`F~ztH}uHDeD#XM zVPLc%91+kq0DilQG)nHmO8)_6_{Z=ZkiUt8OF^#Pb^_4_TiZc_j-`nVNGc-fRS;sY zCEu};l@@ThRks4(*Kd!faRG1I4>QpPs!l5Vtv);D+0<#^l6kIKlCKMH@yE~y+C#6y zqRTs_^O)mw?igIUm2fl5{UCqxX9a3t1jHAwZnmB$N;GMvD_i_oT7N`SYQc1)<0dEI z`HE1RW~?!OQ#vlg6big|&dHVCdj}$W99zfvvo@^dp6HW#L{d-htDz~W2Nhf_b}*h) z_biWpre4qRCK)>h4JxJ2y1s56V2tcHz^$y=WjEamzNjn<{P@*wAZ-CTlU7ZO%Z9_7 zB+mrrzz1}>1c-eM@dA-)gb0<8bRhP6;kbI6L4UJiJh7LxgC~>NmFM~OQF&gcyRBzq zQC}AWJ#sZ&Tq&Ki7SW&e$;~o|EW#{33BQ?L@m_85i$2mH7Vo%$xPlvzasoj>M`rR& z>9?G>IjBYfJO7Ew82-5N>1Mm2{r7#3CX%0iNm*v1>>Cx=^5xcvyTb6a0o{F0&GOrE zAV|#4b?du>H7S9@V>uBCxCNoa5oh6UU>B)ICZ&)@<=R}Y&d$>*qL+D#=W zr~6u$Hp#-1XUy3q3nXoa>M|QP1CBJ6K84L6AaM~=8#f$|dqS@tTH`vDSPWaNJZrGf z8w)HgLM_)CQR|6pIY99f?HCHIt&2MRmYeS3BimkYVE!fuST^^hhowCph3yHRAIrJb zZ0J#3$X#-Uw`gpI*Nl8&AHaUyxW`R!x2BvK5~o9i1kI^$s+CKY7P#ds!drI^Tj>0SxfME=~7Yrf0mH4~~z6XA^k7$uY-0mJzvgnH&YF(30c_ zM&=jg+}c`6NrBXu{1gaCp8!z6SDu9f$?mu8Afdh|Fin;cz)Jg5rc>AwM0X7Urw-4u zu;Y-7U*F_SE(u)wRO0%xo;dH1i)>!JAp~FY8xDi;C-(*?qOJ>61A3? zS|LI}A5t`1t_04Zb$`9xk_JozXQ(=~%bj*X^*nEij;RAOQxUMT=Kxa!`mj7J8Cv(^ z`62I0tMg#4r0Yh(Ui8Mw>%z$##X5Z zsqnM8h)+0tH*HjKJmbV};18d|yAHa7tEpOh213#QG9dx6wGIvh2PjWGuX}{Zq*|B`L5B>|KjQRGVbQ#w_y zPX7_%8QnF?N^sX$qJwC_D_Q`HUhX)CiDB`VxbQilGRGfhl;c07i42XNv0;5zRtTU2 z80QV3*T|ucUNA#cgq`#)l*D1L#1lH@AQfNR`%p#&+JT>?)(U)Y`IS#pW|dOT5J=j! zmlCGSiw&0lVDh6=Y&Og^5p{0BuTSTCxJV)&4Y7)kMcA1yU&vjnZolbBjcnb?KwG$q z5i!axBbsA?({Ta-crv5E{{dL#k;?}G+T+E;X?6LQHr(}+P&!h6bvH2b29!Mwg8kYebNqsg#yOOzS-{kPg0uEZu0b|kj*m8F2}a$A=?ho%9j7I z+k)8m^!V`$R=artz`=LWMd{$c?Od&R&|ryBqmy%IirfOACYJSl{)@e(MR?l+6@9RaP0}CP~?$ezphh)~GT7 zVGQge@%a&{ElQ1z+enqGu`fyL2?Q+MR^~j%Oe7PuLgL`NVHCTpm{Df>n5#fv00 zin@*NT?R10i!JDzei!66c80KnKRSAWCHl({osjoY&W4pEyIasWzt6o#?>tsrJic|n zRkBroseb9Yew{c60VIRG${}=Ymv3eAol^|hO|&l#V{&4^HV=(fie%`S34xTM&5Y>G{MJMHIr6i!%@E||LEZDb74EGQvR7;lWkt^s*#T*3 z`3H^(Y(*_QhPZ_-!nTM^X%5(KFYne#rwY{V0H1sh2O!H(?qCj<%Z*nTOp5^@h6?0oMwvsk!61f!aS9HYo zXR)KMcW$@w4hj{UpWk239l zIf|a?+rqfD+mKb@Luz4PACX=<+g`rZw)x-`bzrj6@!(*yY1=gh)vSokZ3Fs6{kgk9 zgJb40<3;!POZHi{4f1%$ptS+SY}(u_zKteH?TH9GukwK-+pndM?7QWWyLFOU({H6J zFavbxV;oUtvQhpsNOXWtu&B5?u|nRypNHM$CCEL0`L zK(-}rc8oN=LL?4u>}zlYc)VAV$o4MnEk4=_T3ePC$qyhUC6H&RGp<|&(oV?3td=xdi3-l&VgTMIW_8fyQ^ov!EjHOj*IX2-O08jS%NjE8kp0Mwxv z{?qRNuvhNSd?htp9vN7*@0RjWR-@%w6*0PQ(R#HZCL;gAsP2vhk8PuJmu>@B!?O?l z>yypw;WN5jxC&h>}U@?U|=8_ z0e>(W`HP76V}H|F93|&jW!ocka>Az+OdFG_O>zIczW8PA6D?YW5s> zt3apSO4tU6ONG?!5-I{_^`+M($qb+*1bpX5-!AN|2mDU}N(Cm^u}|F9U0VH{OGh=M z=m<{^e3!{A8Dl@8(IjOX%nqP?Uc&=9IdKr9c@?s(60OrzDL&g?God@WX2%qOSBIbo z9ey6J)-q?NB{HL6vU!zWZh%Ni|KZ-@ns}a(6c;6&Er$l$HDAVef@L4$B&R1o>gcHC zYRaCk_U8u1wJtZ$`2~Os1&m9!q}0?s*b{2fd5hNw0@yJnQG>hwTYS`QMaQcZ)s@Tb zvx%{$OfAUCx9`lQG+uA9G1>k~byv#8W!TrO9fCV)YCqj2Th=6%7RqkRIyR6s5d1i;o3Bm;P$z5UGKQl>#D<=>5>1le$mO+4S*4BDLuF`Y@JJ*7aZzWN zKB~v23vFx!cp4X5lZ`?@ek{&BZ{QDY0W4PK84OfdC~ zaOY)cNKge6ep$SIMO0u!`sDgt*DXMR&dEzrrF!n^>D>U}dmi*f+7UUg#~t&~rI>u^ zB2wFYf+Fgw&)H>f zKOlu3AE~*P`KgA7KHB~&?gv~>CHD&HJkh|Te{Uxn!8Xh^;RMffIP+Ng1jyyhQ6$EnAN^&j6(yF(Mw3s7bGCh!r^!J#aHOuBldpIj zSdaxU$L{rnkh`(vBuZR!l&q6su|&hA&gEy{?bDL*Kw=3y4`;g?V)eEGwOel&M<$~8 zYk>q8EI9vQ(cxEWvio~1@#K%zVzjT^2}5)K4VP^26l^u{UIVNF(L}-e2w45(J-DzdZYcEt;IC-^HGl{SJ%|M ztFkh1rovn`M(HOBPd{AYo;mMh^)7MTYhH{=@ioN141U{~rzGf4{gMzR*g$gtHuI%8 z`CdlK!>4U@l?Ku9Ik*=ZxVUN?k zAb1w#9d_7)FcJC1rcJ&0H|vF{aRHoZGvYY&2NVVF2Ax`&vQP1A^B_IYeUkZQ07vK*j)4~&2Pw5i`1a~nyRNjlr z62i)o|~mpz)rsL zrwqEOBYCS8nxn1j*bHeHeFhQ+RzpIQcs`PBHNA-pDVkg;xga>R<$|Z0hnEL*eA%;; zX|lk?c5KC{dxUf~|5mKPti8;;-R4;YbORQ0z>RzSx%U4SFMi=2dG{zb-->iW{<~*X z&Vp)DC`mf56f?iSH%vsZFEQ!XvA7paFvlKCvtu=C{i-NAG71`gKQ`66Gzh1d#6evj zx-KeyDxjC&RDLVv;#FSmN0u#iS&^qfin&iQg_6r`(bq5Pd(?J6dJHSUoCssJd=cv# z;0)<)byh}uPtxHB@}e2yBOnssgo$1W?XQOaS{e+DE!Y}bL0rks1clAEx%fOdWj+?c0JFB%S z5RzX<36E8KOVxDTFZ-Il3dfLge$&OX+%dBTKCymD0b}ujkLS=(fH_A_36E&&2J{~MB`gOJ$aR{KBU4@A zuF!-I?k5{F?M+4ZePg|ge03YE=k-ngYP)zJLgZdaQK7h0685Uc4QGh@$)`O1;MMI% z4ko+q?@oWYIAV)m%C3aC@4UY_W%Y2j>a6U78#vqE{}}GMW3%28qxVDyNHaO7pfRr^ z0z6Lnin|IAq|Z-C!~XQ*@d&u#j*<0hbc&v~6Dn)XIvOEw;Mh{>6xb?DHAEh5%dS}P z<^DQu;B{rqrKo?&URPxglUA3SX=#Ht*r*8pN4(&~`|NPvWeeIjJr2D`(oEM<&}hze z`NxLdo3$|xJrkKNd0@or<+ah;wP!7FMS@-L+rei6X)y?TM!V3Ozj4(;btd zca1x}Eu-*BJ}vNp>CqVlQevWi;zWSl{yxOyqgh>#rj-@zS4$IC7o2@f&y=Xl{!tQ! z_Q>a7>E)amHMsi5UqzLDc~+QtOt6jmSz;FN-6Zq%l|n@xaH8Urz{xVGD1 z%pFlxUSw-<+{AxS2Lo85ax?hPN86!5dL#{7Iq#g^O6z7mofjB^i32?9>taJx{n*VD z<9E&r1pwVn(j=(HkljM-R;nwez2ThkkQ!G3+p{ZizQ;a)s*Bhf(t+Z}5Zs5_iv$6` zdkNTP3GK6Bf5!%^yw&3;)dr6}$b27Fd+DKm^AlcN)-<_l|E}+iR1Ar%74YH!(4O7| zVP^mFXOu91CirQ_=97cqlVKvvN#-;=&$#MITpAa!6AP6(v5lAdd>=~vVO4rfNaZ<| z77-Po;VMB{mnz{DA9MTd##<)-h~~{rE+`?KAFXpL_i=(-EnoB;e1-ewrz~$gj=*I6 ztN1{<2CPcqE?f;X2u4NFt>CE>U=YK)iBd6&651{oejUOxQIGfb`0532?@yxNcg6km zp~=SW^9e+aUO;csf8>qz9A89KDCc^<{R20$^_!~@_#UR}-q{utFyve-d&iBpkBT6gWteEn^D5_S0#kN?JH+Yk{VW)_WXZCd2&ZGuf8Qip;pl_6 ze|B3|x#D(!gpsYs9{W-YoO&E@_uwr*{~jLs!?v)|Yq+IC(pQ>sc(y%A0--gNog(P`Z7E~AMD?yn*o-MfR{N|E6Pfl8|6!?X}ci0yP*(EB~B{FcR z1(=eseBhBOv|}|IzJPZVdp+hJ7rifk=Ot}$1%r>S-6#@~;=U}$i}9&F2NYTe#!GAb zW<(z0JrcyC+e{i|}s~tl>Z0B8s1nmX3>-wRRgiy{p7Y%pfgpR;QFhv?nsQlxltKUDabr>Q6 z8yiL`8d{ZszI(I_th6v2PVe9Dvf32F@n0Q(06vI}fAHB>Lnw@1231B)dMXRxYwzrW z>sEw>f#y*k*>WmxwV;)3-5$=mhlhJRg_2%6{VRz6A`48Yfx?8fF0A^2n3qCyJes#R zT8?Ke7-VDa@#8Ife%5q+?4O&)9jri$6V_rYU{^)RIpPkty@qAL@>Gz}-d&R>-ZzEI zFwqec;a_71g$dgJbL-Xyqi--JfW8wOp3&kM8Ta&~-(`w0JB{F@GZoH*YdhiyQH|He9TgozxafHdiilO0Mvz__{2qyarDcok|HM~kGSyobpIW%LQD|G-i&ej@ z9p5&54_$|})1SgS@DyTXepOS5geczC&0O@(m7ba&+9{2AbZDt z4DWK9@%-TcLg2DDj41c-wUx7~@lx1kuV2zx5`Sv;m5-L#YsDg4f=CMUdocA$5xjo}8 zbEoe*^n5s3f{n%txZ1iIzLazHD%t_|ZvRVw^@+RJw{T1G4qi*qhgLX}a{s!&c$oAT z5CF7g?;_2VcPMU$4m_(=5u7k(wmmTZoSBivvJys#PQAtLaBCy@#Gu{;*)5EoEGd9K zmXW;=_A_2%Vz27a-|$AQd@-ZuX`tKe_`Uk9*`8jtSk*lH%We;!@2xYjL9w)^&T)Ux zWb;yB)++u}`UR*Dap2QnzOSw-hsEkWJ!_i>0u#EHV&ZZS3%$RJf8U>^A_lt7S*#qm zT9Bn5^?4rG_}24F?t<%z>PZ``*9Vkh0&>P*MTp~01?bjR{|6n!0GKVNn4zTKKjK6tiBf?#rc!%G2c1dRfI~|!iT$M-5mGf!K zj@*Iku}_{w>+>ZI)hphq#@=jNd%-T2m1Cl}bxs`q^e78GcFD3NM1V$b?fp75m7WLg z@8Y1BcqqKh?&1H9LwD=&X8$6k>>Pxqo zVK>$LT;D~|Be;4~jh_V4G$|n5dhy59zCHm=H!u)H9EsA{0Jsn92~wqyMH*yR6M z*dS?PIy^0I3gJ0Yr!SZpmz>yjdY z5;tOg#bGchjlnRI$uG5ud0J0!p2DwgR^m8-M3sIzFBy`76iYtK1Ft=J;Xp zQ`+a~MR^pikfLlt2sIC;BLC$j`-@UnMLBD_BfI&p1N5`&#jKoYHaRz)Y|vFYIs!6CVA zpwd!{IH=ae_I#mgI=>-Ff*vZ3YC#|G+tbIg^+)sNnIR@^yUvNw9$$K_SHRDT4eZRZC zC>JKqxv;;Y)AibWc1)3^@ba4uY_iBk78v<&igPV}*@oJ@LHEb6(Bi^s-%>UJNJ=r}V-4?O!BV-709g>*>uzbeF-JX*+dQN7avR*Q-t z_$UOUkSI!Ojc+`ATDYf@K!~Y{!e)A%?!^CxM*`kJa{@vBt}l2cw388gzJ`E>{LZ2W zVt*fgC8jTm^Q^B3d=LS&jX@lkvug(6KzWahXZ+un_&l>aOs8)rnG_cDk5ob z2q=Tc@uRX`#>Acd-DL{`Qkv1jPBBBpa_X!1z`A&J`9{zve8?tlkEY?ZY&SYJ{fYH4P=jPYW61)OEw+5adY2pC zSYf(5DNhSG{MGbLbmB%(8Xpe zwHQ|&2mO*+Z))3eLy*xtkB37kba%>^)%GL-KLU)hw%%hKHA}hRIe*Ve-)DcN?@Ya# zeb9YJFI!J4{=7lpSUK}y0Z{R>V0=Mj)6OecyW!S9y>fT7@=9PYpl`&eK-*z6zQb!(TVk|*r+X07^ zUEtp)#F><1{;Bsl!rfg~r4eo9RjK5Cchr?{rb+!->ykr2O8e}hef6w-o+sm>*G%D_ z5CjRChF$oI^B=rHD-HV&5ye5>o+143{sFuNR{pNmT3&-mds*7>GhKVqi;o3^dwWbx zcyGku=2Eh{DS75%BjGef9cfiscNbS;@|B=L!~njJQI|AIfL@>ib~i02Z2Ks^(fVbd z{5LKL$H=Jm6U`Y!`8-ErM;`xW*A>H6v#06M`P1lv*7z55u&Fefrd^Es-CEac=n+@{ zn_2zGWicW>ovAZG=*D8Y4^zY{G1=B@*u(>50Bh~y?`kB})K^U_Q}!Q~QNQI8qrTez zIO&TtSoB-@RfkuRBLxJ2#u)9HUsA6thYp1=_>buc~D|$(ul*~KXEOM!lHV|j8w5em;2G3@f z`B)I~W+3y=fCW<|YrP1O3$y-^wgg|MZNgE1D_R?B8{;VOtS$p3(T?oc<7PL|qkKu` zuz-XFupEt~ZKS`sVH+&%c0S12waD6YP%2!%anOKIH~=U OlY#DqbA@N@LjDgw+L_G& diff --git a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java index 99994e6..4de8c9e 100644 --- a/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java +++ b/source/pro/litvinovg/libreoffice/metadata/views/EditorGUI.java @@ -288,7 +288,7 @@ public class EditorGUI extends JFrame { } private void configureWindow() { - setIconImage(Toolkit.getDefaultToolkit().getImage(EditorGUI.class.getResource("/pro/litvinovg/libreoffice/metadata/resources/webcam.png"))); + 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); From 7e85c019846651a985eb341ab65bfce6e084e640 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 23 Apr 2020 16:45:33 +0200 Subject: [PATCH 30/31] Update 0.4.1 --- metadataeditor.update.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metadataeditor.update.xml b/metadataeditor.update.xml index 1739354..b46d38e 100644 --- a/metadataeditor.update.xml +++ b/metadataeditor.update.xml @@ -2,9 +2,9 @@ - + - + From cb51dd940c59193f2122b563064153d20cffa1a2 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 23 Apr 2020 19:03:06 +0200 Subject: [PATCH 31/31] Set main icon --- description.xml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/description.xml b/description.xml index e25d158..9a34e6b 100644 --- a/description.xml +++ b/description.xml @@ -1,16 +1,20 @@ - + + + + + + + MetadataEditor - - - - - - + + + +