Working on outline metadata

This commit is contained in:
Georgy Litvinov 2020-04-09 15:03:47 +02:00
parent c37b01eb92
commit 71776fa54b
4 changed files with 220 additions and 17 deletions

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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<MetadataElement> 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<MetadataElement>();
}
}
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<MetadataElement> metadataTempElements = new ArrayList<MetadataElement>();
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;
}
}

View file

@ -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() {