Initialized project
This commit is contained in:
parent
072e974320
commit
11341e4b14
53 changed files with 2868 additions and 46 deletions
19
.classpath
Normal file
19
.classpath
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<manifest:manifest>
|
||||
<manifest:file-entry manifest:full-path="docSettings/" manifest:media-type="application/vnd.sun.star.basic-library"/>
|
||||
<manifest:file-entry manifest:full-path="Events.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/>
|
||||
</manifest:manifest>
|
61
build.gradle
61
build.gradle
|
@ -1,13 +1,64 @@
|
|||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse'
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
|
||||
compileClasspath 'org.libreoffice:jurt:5.3.2'
|
||||
compileClasspath 'org.libreoffice:juh:5.3.2'
|
||||
compileClasspath 'org.libreoffice:ridl:5.3.2'
|
||||
compileClasspath 'org.libreoffice:unoil:5.3.2'
|
||||
compileClasspath group: 'org.slf4j', name: 'slf4j-api', version: '1.7.32'
|
||||
compileClasspath 'ch.qos.logback:logback-classic:1.2.6'
|
||||
compileClasspath 'ch.qos.logback:logback-core:1.2.6'
|
||||
compileClasspath 'org.apache.tika:tika-core:2.1.0'
|
||||
}
|
||||
|
||||
|
||||
task oxtjar(type: Jar) {
|
||||
archiveName 'docsettings_oxt.jar'
|
||||
manifest {
|
||||
attributes("Implementation-Title": rootProject.name,
|
||||
"Implementation-Version": project.version,
|
||||
"RegistrationClassName" : "pro.litvinovg.docsettings.RegistrationHandler",
|
||||
"Class-Path" : "jasp.jar parser.jar")
|
||||
}
|
||||
from('src/main/java') {
|
||||
include '**/*.classes'
|
||||
include 'logback.xml'
|
||||
include 'pro/litvinovg/docsettings/resources/*.png'
|
||||
include 'pro/litvinovg/docsettings/localizations/*.properties'
|
||||
}
|
||||
from (sourceSets.main.output){
|
||||
include 'pro/litvinovg/**/*.class'
|
||||
include 'ch/**/*'
|
||||
include 'org/slf4j/**/*'
|
||||
}
|
||||
from {
|
||||
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
task oxt(type: Zip) {
|
||||
from './'
|
||||
dependsOn = [ 'oxtjar' ]
|
||||
from './oxt/'
|
||||
include '*'
|
||||
include '*/*'
|
||||
include '*/*/*'
|
||||
include '*/*/*/*'
|
||||
exclude 'docSettings.oxt'
|
||||
exclude '.*'
|
||||
exclude 'build.gradle'
|
||||
exclude 'translations.ods'
|
||||
exclude 'update.xml'
|
||||
from ('build/libs/docsettings_oxt.jar'){
|
||||
include '*'
|
||||
}
|
||||
archiveName 'docSettings.oxt'
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
Extension for document settings configuration.
|
||||
For now consists of workaround for layout bug since LO 6.4
|
||||
https://bugs.documentfoundation.org/show_bug.cgi?id=134782
|
|
@ -1,3 +0,0 @@
|
|||
Расширение исправления настроек документов
|
||||
В данный момент содержит исправления для бага, возникшего с версии 6.4
|
||||
https://bugs.documentfoundation.org/show_bug.cgi?id=134782
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
|
||||
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="Events" script:language="StarBasic" script:moduleType="normal">Sub execOnDocumentLoad
|
||||
Dim fixCompatibilityOption As Boolean
|
||||
fixCompatibilityOption = true
|
||||
If fixCompatibilityOption Then
|
||||
Dim oDocSettings As Object
|
||||
oDocSettings = ThisComponent.createInstance( "com.sun.star.document.Settings" )
|
||||
If oDocSettings.supportsService("com.sun.star.text.DocumentSettings") Then
|
||||
oDocSettings.setPropertyValue("AddParaSpacingToTableCells", false)
|
||||
EndIf
|
||||
EndIf
|
||||
End Sub
|
||||
</script:module>
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd">
|
||||
<library:library xmlns:library="http://openoffice.org/2000/library" library:name="docSettings" library:readonly="false" library:passwordprotected="false">
|
||||
</library:library>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd">
|
||||
<library:library xmlns:library="http://openoffice.org/2000/library" library:name="docSettings" library:readonly="false" library:passwordprotected="false">
|
||||
<library:element library:name="Events"/>
|
||||
</library:library>
|
46
oxt/Addons.xcu
Normal file
46
oxt/Addons.xcu
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<oor:component-data oor:package="org.openoffice.Office" oor:name="Addons"
|
||||
xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<node oor:name="AddonUI">
|
||||
|
||||
<node oor:name="Images">
|
||||
<node oor:name="pro.litvinovg.docsettings.openGUIImage" oor:op="replace">
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:pro.litvinovg.libreoffice.DocSettings?openGUI</value>
|
||||
</prop>
|
||||
<node oor:name="UserDefinedImages">
|
||||
<prop oor:name="ImageBigURL">
|
||||
<value>vnd.sun.star.extension://pro.litvinovg.libreoffice.docsettings/icons/button_icon.png</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
||||
<node oor:name="OfficeToolBar">
|
||||
<node oor:name="pro.litvinovg.libreoffice.docsettings.toolbar" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value>Document settings panel</value>
|
||||
</prop>
|
||||
<prop oor:name="Docked" oor:op="fuse"><value>true</value></prop>
|
||||
<node oor:name="t01" oor:op="replace">
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:pro.litvinovg.libreoffice.DocSettings?openGUI</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en-US">Open document settings</value>
|
||||
<value xml:lang="ru-RU">Открыть настройки документа</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
||||
|
||||
|
||||
</node>
|
||||
</oor:component-data>
|
|
@ -4,9 +4,9 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Events"
|
|||
oor:package="org.openoffice.Office">
|
||||
<node oor:name="ApplicationEvents">
|
||||
<node oor:name="Bindings">
|
||||
<node oor:name="OnLoad" oor:op="replace">
|
||||
<node oor:name="OnLoadFinished" oor:op="replace">
|
||||
<prop oor:name="BindingURL" oor:type="xs:string">
|
||||
<value>vnd.sun.star.script:docSettings.Events.execOnDocumentLoad?language=Basic&location=application</value>
|
||||
<value>service:pro.litvinovg.libreoffice.DocSettings?onLoad</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
8
oxt/META-INF/manifest.xml
Normal file
8
oxt/META-INF/manifest.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
|
||||
<manifest:file-entry manifest:full-path="Events.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/>
|
||||
<manifest:file-entry manifest:full-path="Addons.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/>
|
||||
<manifest:file-entry manifest:full-path="docsettings_oxt.jar" manifest:media-type="application/vnd.sun.star.uno-component;type=Java"/>
|
||||
<manifest:file-entry manifest:full-path="WriterWindowState.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/>
|
||||
|
||||
</manifest:manifest>
|
27
oxt/WriterWindowState.xcu
Normal file
27
oxt/WriterWindowState.xcu
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<oor:component-data oor:package="org.openoffice.Office.UI" oor:name="WriterWindowState"
|
||||
xmlns:install="http://openoffice.org/2004/installation" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<node oor:name="UIElements">
|
||||
<node oor:name="States">
|
||||
<!-- Used to dock the toolbar in the first toolbar row (by default it's floating) -->
|
||||
<node oor:name="private:resource/toolbar/addon_pro.litvinovg.libreoffice.docsettings.toolbar" oor:op="replace">
|
||||
<prop oor:name="UIName" oor:type="xs:string">
|
||||
<value xml:lang="en">Document settings</value>
|
||||
<value xml:lang="ru">Настройки документа</value>
|
||||
</prop>
|
||||
<prop oor:name="DockPos" oor:type="xs:string">
|
||||
<value>10,0</value>
|
||||
</prop>
|
||||
<prop oor:name="Docked" oor:type="xs:boolean">
|
||||
<value>true</value>
|
||||
</prop>
|
||||
<prop oor:name="DockingArea" oor:type="xs:int">
|
||||
<value>0</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
||||
</oor:component-data>
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:dep="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<identifier value="pro.litvinovg.libreoffice.docsettings"/>
|
||||
<version value="0.0.3"/>
|
||||
<version value="0.0.6"/>
|
||||
<platform value="all"/>
|
||||
<display-name>
|
||||
<name lang="ru">Исправление свойств документов</name>
|
||||
<name lang="en">Docement settings fix</name>
|
||||
<name lang="ru">Управление настройками документов</name>
|
||||
<name lang="en">Docement settings management</name>
|
||||
</display-name>
|
||||
<registration>
|
||||
<simple-license accept-by="admin" suppress-if-required="true" suppress-on-update="true">
|
||||
|
@ -21,6 +21,7 @@
|
|||
</update-information>
|
||||
<publisher>
|
||||
<name lang="en" xlink:href="mailto:public@litvinovg.pro">Georgy Litvinov</name>
|
||||
<name lang="ru" xlink:href="mailto:public@litvinovg.pro">Георгий Литвинов</name>
|
||||
</publisher>
|
||||
<release-notes>
|
||||
<src lang="en" xlink:href="releasenotes.txt"/>
|
2
oxt/description/description_en.txt
Normal file
2
oxt/description/description_en.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
Extension for document settings configuration.
|
||||
Provides a way to create setttings backups and restore from it.
|
2
oxt/description/description_ru.txt
Normal file
2
oxt/description/description_ru.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
Расширение для управления настройками документов
|
||||
Предоставляет возможность создания резервных копий настроек и восстановления из них.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
BIN
oxt/icons/button_icon.png
Normal file
BIN
oxt/icons/button_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -1,6 +1,6 @@
|
|||
The author of this extension is:
|
||||
Georgy Litvinov (public@litvinovg.pro)
|
||||
Copyright 2020.
|
||||
Copyright 2021.
|
||||
|
||||
This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License.
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
Автор расширения:
|
||||
Георгий Литвинов (public@litvinovg.pro)
|
||||
Copyright 2020.
|
||||
Copyright 2021.
|
||||
|
||||
Это расширение является свободным программным обеспечением, вы можете распространять и/или модифицировать его в соответствии с лицензией GNU Lesser General Public License версии 3.0, опубликованной Free Software Foundation.
|
||||
|
|
@ -1,2 +1,4 @@
|
|||
0.0.6 Added settings backup and restore options
|
||||
0.0.5 Removed obsoleted workaround
|
||||
0.0.3 Apply only to writer documents
|
||||
0.0.1 First public release with workaround for https://bugs.documentfoundation.org/show_bug.cgi?id=134782
|
24
src/main/java/logback.xml
Normal file
24
src/main/java/logback.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} %-5level - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<!-- <appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>/home/litvinovg/logs/docsettings-log.txt</file>
|
||||
<append>true</append>
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} %-5level - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender> -->
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
<!-- <root level="error">
|
||||
<appender-ref ref="FILE" />
|
||||
</root> -->
|
||||
<!-- <root level="debug">
|
||||
<appender-ref ref="FILE" />
|
||||
</root> -->
|
||||
</configuration>
|
185
src/main/java/pro/litvinovg/docsettings/DialogHelper.java
Normal file
185
src/main/java/pro/litvinovg/docsettings/DialogHelper.java
Normal file
|
@ -0,0 +1,185 @@
|
|||
package pro.litvinovg.docsettings;
|
||||
|
||||
|
||||
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, "Warning", message);
|
||||
}
|
||||
|
||||
public static void showErrorMessage(XComponentContext context, XDialog dialog, String message) {
|
||||
showMessageBox(context, dialog, MessageBoxType.ERRORBOX, "Error", 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package pro.litvinovg.docsettings;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.star.lang.XSingleComponentFactory;
|
||||
|
||||
//import pro.litvinovg.docsettings.gui.ConfigurationWindow;
|
||||
//import pro.litvinovg.docsettings.gui.ConversionExecutor;
|
||||
|
||||
import com.sun.star.lib.uno.helper.Factory;
|
||||
import com.sun.star.lib.uno.helper.WeakBase;
|
||||
import com.sun.star.registry.XRegistryKey;
|
||||
import com.sun.star.uno.XComponentContext;
|
||||
|
||||
import pro.litvinovg.docsettings.document.ODFDocument;
|
||||
import pro.litvinovg.docsettings.gui.MainWindow;
|
||||
import pro.litvinovg.docsettings.settings.Backups;
|
||||
import pro.litvinovg.docsettings.settings.Settings;
|
||||
|
||||
public final class DocSettingsExtension extends WeakBase
|
||||
implements com.sun.star.lang.XServiceInfo, com.sun.star.task.XJobExecutor {
|
||||
private final XComponentContext context;
|
||||
private static final String m_implementationName = DocSettingsExtension.class.getName();
|
||||
private static final String[] m_serviceNames = { "pro.litvinovg.libreoffice.DocSettings" };
|
||||
private static final Logger logger = LoggerFactory.getLogger(DocSettingsExtension.class);
|
||||
|
||||
public DocSettingsExtension(XComponentContext componentContext) {
|
||||
context = componentContext;
|
||||
};
|
||||
|
||||
public static XSingleComponentFactory __getComponentFactory(String sImplementationName) {
|
||||
XSingleComponentFactory xFactory = null;
|
||||
|
||||
if (sImplementationName.equals(m_implementationName))
|
||||
xFactory = Factory.createComponentFactory(DocSettingsExtension.class, m_serviceNames);
|
||||
return xFactory;
|
||||
}
|
||||
|
||||
public static boolean __writeRegistryServiceInfo(XRegistryKey xRegistryKey) {
|
||||
return Factory.writeRegistryServiceInfo(m_implementationName, m_serviceNames, xRegistryKey);
|
||||
}
|
||||
|
||||
// com.sun.star.lang.XServiceInfo:
|
||||
public String getImplementationName() {
|
||||
return m_implementationName;
|
||||
}
|
||||
|
||||
public boolean supportsService(String sService) {
|
||||
int len = m_serviceNames.length;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (sService.equals(m_serviceNames[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String[] getSupportedServiceNames() {
|
||||
return m_serviceNames;
|
||||
}
|
||||
|
||||
// com.sun.star.task.XJobExecutor:
|
||||
public void trigger(String action) {
|
||||
switch (action) {
|
||||
case "openGUI":
|
||||
try {
|
||||
MainWindow.runGUI(context);
|
||||
} catch (Throwable e) {
|
||||
DialogHelper.showErrorMessage(context, null, e.getLocalizedMessage());
|
||||
}
|
||||
break;
|
||||
case "onLoad":
|
||||
try {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
onLoad();
|
||||
} catch (Exception e) {
|
||||
DialogHelper.showErrorMessage(context, null, e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
DialogHelper.showErrorMessage(context, null, e.getLocalizedMessage());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DialogHelper.showErrorMessage(context, null, "Unknown action: " + action);
|
||||
}
|
||||
}
|
||||
|
||||
private void onLoad() {
|
||||
ODFDocument document = null;
|
||||
try {
|
||||
document = new ODFDocument(context);
|
||||
} catch (Exception e) {
|
||||
logger.debug("Ops", e);
|
||||
return;
|
||||
}
|
||||
Backups backups = new Backups();
|
||||
ExtensionConfig config = ExtensionConfig.getInstance();
|
||||
document.readSettings();
|
||||
document.readBackups(backups);
|
||||
if (!document.hasBackups(backups)) {
|
||||
backups.create(document.getCurrentSettings());
|
||||
document.writeBackups(backups);
|
||||
return;
|
||||
}
|
||||
if (config.getAutoRestore()) {
|
||||
Settings settings = backups.getLatest();
|
||||
boolean isSettingsChanged = document.compareWithBackup(settings);
|
||||
if (isSettingsChanged) {
|
||||
document.restoreSettings(settings);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
41
src/main/java/pro/litvinovg/docsettings/ExtensionConfig.java
Normal file
41
src/main/java/pro/litvinovg/docsettings/ExtensionConfig.java
Normal file
|
@ -0,0 +1,41 @@
|
|||
package pro.litvinovg.docsettings;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ExtensionConfig {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ExtensionConfig.class);
|
||||
private static final String AUTO_RESTORE = "autoRestore";
|
||||
private static ExtensionConfig extensionSettings = null;
|
||||
private Preferences storage;
|
||||
|
||||
public static ExtensionConfig getInstance() {
|
||||
if (extensionSettings != null) {
|
||||
return extensionSettings;
|
||||
}
|
||||
extensionSettings = new ExtensionConfig();
|
||||
return extensionSettings;
|
||||
}
|
||||
|
||||
private ExtensionConfig() {
|
||||
storage = Preferences.userRoot().node(this.getClass().getName());
|
||||
}
|
||||
|
||||
public boolean getAutoRestore() {
|
||||
return storage.getBoolean(AUTO_RESTORE, false);
|
||||
}
|
||||
|
||||
public void setAutoRestore(boolean value) {
|
||||
storage.putBoolean(AUTO_RESTORE, value);
|
||||
try {
|
||||
storage.sync();
|
||||
} catch (BackingStoreException e) {
|
||||
logger.debug("Ops", e);
|
||||
}
|
||||
}
|
||||
}
|
60
src/main/java/pro/litvinovg/docsettings/FileHelper.java
Normal file
60
src/main/java/pro/litvinovg/docsettings/FileHelper.java
Normal file
|
@ -0,0 +1,60 @@
|
|||
package pro.litvinovg.docsettings;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
62
src/main/java/pro/litvinovg/docsettings/Localizer.java
Normal file
62
src/main/java/pro/litvinovg/docsettings/Localizer.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
package pro.litvinovg.docsettings;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class Localizer {
|
||||
|
||||
private Locale currentLocale;
|
||||
private String resourceBundle = "pro.litvinovg.docsettings.localizations.docsettings";
|
||||
private ResourceBundle translations;
|
||||
private boolean isOld = false;
|
||||
private static Localizer localizer = null;
|
||||
private Localizer() {
|
||||
currentLocale = Locale.getDefault();
|
||||
translations = ResourceBundle.getBundle(resourceBundle, currentLocale);
|
||||
this.isOld = isOldJava();
|
||||
}
|
||||
|
||||
public static Localizer getInstance() {
|
||||
if (localizer != null) {
|
||||
return localizer;
|
||||
}
|
||||
localizer = new Localizer();
|
||||
return localizer;
|
||||
}
|
||||
public static String get(String name) {
|
||||
Localizer.getInstance();
|
||||
return localizer.getTranslation(name);
|
||||
}
|
||||
|
||||
public String getTranslation(String name) {
|
||||
if (translations != null && translations.containsKey(name)) {
|
||||
String translation = translations.getString(name);
|
||||
if (isOld) {
|
||||
try {
|
||||
return new String(translation.getBytes("ISO-8859-1"), "UTF-8");
|
||||
} catch(UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
return translation;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
|
||||
}
|
||||
private boolean isOldJava() {
|
||||
try {
|
||||
String versionString = System.getProperty("java.class.version");
|
||||
Float version = Float.parseFloat(versionString);
|
||||
if (version < 53) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getLocalizedMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pro.litvinovg.docsettings.DocSettingsExtension
|
175
src/main/java/pro/litvinovg/docsettings/RegistrationHandler.java
Normal file
175
src/main/java/pro/litvinovg/docsettings/RegistrationHandler.java
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*************************************************************************
|
||||
*
|
||||
* The Contents of this file are made available subject to the terms of
|
||||
* either of the GNU Lesser General Public License Version 2.1
|
||||
*
|
||||
* Sun Microsystems Inc., October, 2000
|
||||
*
|
||||
*
|
||||
* GNU Lesser General Public License Version 2.1
|
||||
* =============================================
|
||||
* Copyright 2000 by Sun Microsystems, Inc.
|
||||
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
* The Initial Developer of the Original Code is: Sun Microsystems, Inc..
|
||||
*
|
||||
* Copyright: 2002 by Sun Microsystems, Inc.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Cedric Bosdonnat
|
||||
*
|
||||
*
|
||||
************************************************************************/
|
||||
package pro.litvinovg.docsettings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.sun.star.lang.XSingleComponentFactory;
|
||||
import com.sun.star.registry.XRegistryKey;
|
||||
|
||||
/**
|
||||
* Component main registration class.
|
||||
*
|
||||
* <p><strong>This class should not be modified.</strong></p>
|
||||
*
|
||||
* @author Cedric Bosdonnat aka. cedricbosdo
|
||||
*
|
||||
*/
|
||||
public class RegistrationHandler {
|
||||
|
||||
/**
|
||||
* Get a component factory for the implementations handled by this class.
|
||||
*
|
||||
* <p>This method calls all the methods of the same name from the classes listed
|
||||
* in the <code>RegistrationHandler.classes</code> file. <strong>This method
|
||||
* should not be modified.</strong></p>
|
||||
*
|
||||
* @param pImplementationName the name of the implementation to create.
|
||||
*
|
||||
* @return the factory which can create the implementation.
|
||||
*/
|
||||
public static XSingleComponentFactory __getComponentFactory(String sImplementationName ) {
|
||||
XSingleComponentFactory xFactory = null;
|
||||
|
||||
Class[] classes = findServicesImplementationClasses();
|
||||
|
||||
int i = 0;
|
||||
while (i < classes.length && xFactory == null) {
|
||||
Class clazz = classes[i];
|
||||
if ( sImplementationName.equals( clazz.getCanonicalName() ) ) {
|
||||
try {
|
||||
Class[] getTypes = new Class[]{String.class};
|
||||
Method getFactoryMethod = clazz.getMethod("__getComponentFactory", getTypes);
|
||||
Object o = getFactoryMethod.invoke(null, sImplementationName);
|
||||
xFactory = (XSingleComponentFactory)o;
|
||||
} catch (Exception e) {
|
||||
// Nothing to do: skip
|
||||
System.err.println("Error happened");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return xFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the services implementation informations to the UNO registry.
|
||||
*
|
||||
* <p>This method calls all the methods of the same name from the classes listed
|
||||
* in the <code>RegistrationHandler.classes</code> file. <strong>This method
|
||||
* should not be modified.</strong></p>
|
||||
*
|
||||
* @param pRegistryKey the root registry key where to write the informations.
|
||||
*
|
||||
* @return <code>true</code> if the informations have been successfully written
|
||||
* to the registry key, <code>false</code> otherwise.
|
||||
*/
|
||||
public static boolean __writeRegistryServiceInfo(XRegistryKey xRegistryKey ) {
|
||||
|
||||
Class[] classes = findServicesImplementationClasses();
|
||||
|
||||
boolean success = true;
|
||||
int i = 0;
|
||||
while (i < classes.length && success) {
|
||||
Class clazz = classes[i];
|
||||
try {
|
||||
Class[] writeTypes = new Class[]{XRegistryKey.class};
|
||||
Method getFactoryMethod = clazz.getMethod("__writeRegistryServiceInfo", writeTypes);
|
||||
Object o = getFactoryMethod.invoke(null, xRegistryKey);
|
||||
success = success && ((Boolean)o).booleanValue();
|
||||
} catch (Exception e) {
|
||||
success = false;
|
||||
e.printStackTrace();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all the UNO implementation classes.
|
||||
*/
|
||||
private static Class[] findServicesImplementationClasses() {
|
||||
|
||||
ArrayList<Class> classes = new ArrayList<Class>();
|
||||
|
||||
InputStream in = RegistrationHandler.class.getResourceAsStream("RegistrationHandler.classes");
|
||||
LineNumberReader reader = new LineNumberReader(new InputStreamReader(in));
|
||||
|
||||
try {
|
||||
String line = reader.readLine();
|
||||
while (line != null) {
|
||||
if (!line.equals("")) {
|
||||
line = line.trim();
|
||||
try {
|
||||
Class clazz = Class.forName(line);
|
||||
|
||||
Class[] writeTypes = new Class[]{XRegistryKey.class};
|
||||
Class[] getTypes = new Class[]{String.class};
|
||||
|
||||
Method writeRegMethod = clazz.getMethod("__writeRegistryServiceInfo", writeTypes);
|
||||
Method getFactoryMethod = clazz.getMethod("__getComponentFactory", getTypes);
|
||||
|
||||
if (writeRegMethod != null && getFactoryMethod != null) {
|
||||
classes.add(clazz);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
line = reader.readLine();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
in.close();
|
||||
} catch (Exception e) {};
|
||||
}
|
||||
|
||||
return classes.toArray(new Class[classes.size()]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package pro.litvinovg.docsettings;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import pro.litvinovg.docsettings.document.ODFDocument;
|
||||
import pro.litvinovg.docsettings.settings.Backups;
|
||||
|
||||
public class StandaloneApplication {
|
||||
private static final Logger logger = LoggerFactory.getLogger(StandaloneApplication.class);
|
||||
|
||||
public static void main(String args[]) {
|
||||
if (args.length == 0 ) {
|
||||
logger.debug("Error. No arguments found. Exit.");
|
||||
return;
|
||||
}
|
||||
final String filePath = args[0];
|
||||
File file = new File(filePath);
|
||||
if (!file.exists()) {
|
||||
logger.debug("Error. File doesn't exist. Exit.");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,357 @@
|
|||
package pro.litvinovg.docsettings.document;
|
||||
|
||||
import static pro.litvinovg.docsettings.settings.StorageUtils.getDocFromString;
|
||||
import static pro.litvinovg.docsettings.settings.StorageUtils.getSettingsElement;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.tika.Tika;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import com.sun.star.beans.PropertyValue;
|
||||
import com.sun.star.beans.XPropertyContainer;
|
||||
import com.sun.star.beans.XPropertySet;
|
||||
import com.sun.star.beans.XPropertySetInfo;
|
||||
import com.sun.star.chart.TimeUnit;
|
||||
import com.sun.star.document.XDocumentProperties;
|
||||
import com.sun.star.document.XDocumentPropertiesSupplier;
|
||||
import com.sun.star.frame.XComponentLoader;
|
||||
import com.sun.star.frame.XDesktop;
|
||||
import com.sun.star.frame.XDispatchHelper;
|
||||
import com.sun.star.frame.XDispatchProvider;
|
||||
import com.sun.star.frame.XModel;
|
||||
import com.sun.star.frame.XStorable;
|
||||
import com.sun.star.lang.XComponent;
|
||||
import com.sun.star.lang.XMultiComponentFactory;
|
||||
import com.sun.star.lang.XServiceInfo;
|
||||
import com.sun.star.text.XTextDocument;
|
||||
import com.sun.star.uno.UnoRuntime;
|
||||
import com.sun.star.uno.XComponentContext;
|
||||
import com.sun.star.util.XModifiable;
|
||||
|
||||
import pro.litvinovg.docsettings.DialogHelper;
|
||||
import pro.litvinovg.docsettings.Localizer;
|
||||
import pro.litvinovg.docsettings.gui.MainWindow;
|
||||
import pro.litvinovg.docsettings.settings.Backups;
|
||||
import pro.litvinovg.docsettings.settings.ODFSetting;
|
||||
import pro.litvinovg.docsettings.settings.SettingFactory;
|
||||
import pro.litvinovg.docsettings.settings.Settings;
|
||||
import pro.litvinovg.docsettings.settings.SettingsComparator;
|
||||
|
||||
public class ODFDocument {
|
||||
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ODFDocument.class);
|
||||
|
||||
private XComponentContext context = null;
|
||||
private XDesktop xDesktop = null;
|
||||
private XMultiComponentFactory multiComponentFactory = null;
|
||||
private XComponent currentDocument = null;
|
||||
private String fileName = "";
|
||||
public static final String SETTINGS = "settings.xml";
|
||||
public static final String META = "meta.xml";
|
||||
private Settings currentSettings = null;
|
||||
|
||||
private XStorable storable = null;
|
||||
|
||||
private XComponentLoader loader = null;
|
||||
|
||||
private String url = null;
|
||||
|
||||
public Settings getCurrentSettings() {
|
||||
if (currentSettings.getSize() == 0) {
|
||||
readSettings();
|
||||
}
|
||||
return currentSettings;
|
||||
}
|
||||
|
||||
private String getSettingsContent() {
|
||||
return readInternalFile(SETTINGS);
|
||||
}
|
||||
|
||||
private void setSettingsContent(String settingsContent) {
|
||||
writeInternalFile(SETTINGS, settingsContent);
|
||||
}
|
||||
|
||||
private String getMetaContent() {
|
||||
return readInternalFile(META);
|
||||
}
|
||||
|
||||
/*
|
||||
* private void setMetaContent(String newMetaContent) { writeInternalFile(META,
|
||||
* newMetaContent); }
|
||||
*/
|
||||
|
||||
public ODFDocument(XComponentContext componentContext) throws Exception {
|
||||
this.currentSettings = new Settings();
|
||||
if (componentContext != null) {
|
||||
context = componentContext;
|
||||
multiComponentFactory = context.getServiceManager();
|
||||
|
||||
Object oDesktop = multiComponentFactory.createInstanceWithContext("com.sun.star.frame.Desktop", context);
|
||||
xDesktop = UnoRuntime.queryInterface(XDesktop.class, oDesktop);
|
||||
currentDocument = xDesktop.getCurrentComponent();
|
||||
if (currentDocument == null) {
|
||||
logger.debug("xDesktop.getCurrentComponent() returned null");
|
||||
throw new Exception(Localizer.get("error_document_is_null"));
|
||||
}
|
||||
XModel model = UnoRuntime.queryInterface(XModel.class, currentDocument);
|
||||
if (!isSupported(currentDocument, "com.sun.star.text.TextDocument")) {
|
||||
throw new Exception(Localizer.get("error_document_type_is_not_supported"));
|
||||
}
|
||||
loader = UnoRuntime.queryInterface(XComponentLoader.class, xDesktop);
|
||||
XTextDocument textDoc = UnoRuntime.queryInterface(XTextDocument.class, currentDocument);
|
||||
if (textDoc == null) {
|
||||
throw new Exception("Error. TextDoc is null.");
|
||||
}
|
||||
storable = UnoRuntime.queryInterface(XStorable.class, textDoc);
|
||||
|
||||
if (storable == null || storable.isReadonly()) {
|
||||
throw new Exception(Localizer.get("error_document_is_ro"));
|
||||
}
|
||||
if (!storable.hasLocation() || storable.getLocation().isEmpty()) {
|
||||
throw new Exception(Localizer.get("error_document_is_not_saved"));
|
||||
}
|
||||
|
||||
url = model.getURL();
|
||||
URI uri = new URI(url);
|
||||
File file = new File(uri);
|
||||
if (!file.exists()) {
|
||||
throw new Exception(Localizer.get("error_document_is_null"));
|
||||
}
|
||||
if (!file.canRead()) {
|
||||
throw new Exception(Localizer.get("error_document_is_ro"));
|
||||
}
|
||||
if (!"application/vnd.oasis.opendocument.text".equals(getMimeType(file))) {
|
||||
throw new Exception(Localizer.get("error_document_type_is_not_supported"));
|
||||
}
|
||||
fileName = file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
private String getMimeType(File file) {
|
||||
Tika tika = new Tika();
|
||||
InputStream is;
|
||||
String mime = "";
|
||||
try {
|
||||
is = new FileInputStream(file);
|
||||
mime = tika.detect(is);
|
||||
} catch (IOException e) {
|
||||
logger.debug("Ops", e);
|
||||
}
|
||||
return mime;
|
||||
}
|
||||
|
||||
public void restoreSettings(Settings settings) {
|
||||
closeDocument();
|
||||
restoreFrom(settings);
|
||||
reOpenDoc();
|
||||
}
|
||||
|
||||
public XPropertyContainer getUserDefinedProps(){
|
||||
XDocumentPropertiesSupplier docPropertiesSupplier = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, currentDocument);
|
||||
XDocumentProperties docProperties = docPropertiesSupplier.getDocumentProperties();
|
||||
XPropertyContainer userDefinedProperties = docProperties.getUserDefinedProperties();
|
||||
return userDefinedProperties;
|
||||
}
|
||||
|
||||
public void readSettings() {
|
||||
flushSettings();
|
||||
try {
|
||||
Node configSettings = getSettingsElement(getDocFromString(getSettingsContent()));
|
||||
NodeList settingNodes = configSettings.getChildNodes();
|
||||
for (int i = 0; i < settingNodes.getLength(); i++) {
|
||||
Node settingNode = settingNodes.item(i);
|
||||
ODFSetting setting = SettingFactory.create(settingNode);
|
||||
currentSettings.add(setting);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.debug(e.getMessage());
|
||||
logger.debug("Ops!",e);
|
||||
}
|
||||
}
|
||||
|
||||
private void flushSettings() {
|
||||
currentSettings.clear();
|
||||
}
|
||||
|
||||
public void restoreFrom(Settings settings) {
|
||||
String newSettingsContent;
|
||||
try {
|
||||
newSettingsContent = settings.toSettingsContent(getSettingsContent());
|
||||
writeInternalFile(SETTINGS, newSettingsContent);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.debug("Restore failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void readBackups(Backups backups) {
|
||||
backups.readBackupsFromMetadata(getUserDefinedProps());
|
||||
}
|
||||
|
||||
public boolean hasBackups(Backups backups) {
|
||||
return !backups.isEmpty();
|
||||
}
|
||||
|
||||
public void writeBackups(Backups backups) {
|
||||
backups.writeBackupsToMetadata(getUserDefinedProps());
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void printText(String text) {
|
||||
DialogHelper.showErrorMessage(context, null, text);
|
||||
}
|
||||
|
||||
public void printFileName() {
|
||||
DialogHelper.showErrorMessage(context, null, fileName);
|
||||
}
|
||||
|
||||
private String readInternalFile(String internalFile) {
|
||||
Map<String, String> env = new HashMap<>();
|
||||
String result = "";
|
||||
FileSystem zipfs = null;
|
||||
env.put("create", "true");
|
||||
Path path = Paths.get(fileName);
|
||||
URI uri = URI.create("jar:" + path.toUri());
|
||||
try {
|
||||
zipfs = FileSystems.newFileSystem(uri, env);
|
||||
Path settingsPath = zipfs.getPath(internalFile);
|
||||
byte[] encoded = Files.readAllBytes(settingsPath);
|
||||
result = new String(encoded, "UTF-8");
|
||||
} catch (IOException e) {
|
||||
logger.debug(e.getMessage());
|
||||
logger.debug("Ops!",e);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
zipfs.close();
|
||||
} catch (IOException e) {
|
||||
logger.debug("Ops", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void writeInternalFile(String internalFile, String contents) {
|
||||
Map<String, String> env = new HashMap<>();
|
||||
BufferedWriter writer = null;
|
||||
FileSystem zipfs = null;
|
||||
env.put("create", "true");
|
||||
Path path = Paths.get(fileName);
|
||||
URI uri = URI.create("jar:" + path.toUri());
|
||||
try {
|
||||
zipfs = FileSystems.newFileSystem(uri, env);
|
||||
Path internalPath = zipfs.getPath(internalFile);
|
||||
writer = Files.newBufferedWriter(internalPath, StandardCharsets.UTF_8, StandardOpenOption.WRITE);
|
||||
writer.write(contents);
|
||||
} catch (IOException e) {
|
||||
logger.debug(e.getMessage());
|
||||
logger.debug("Ops!",e);
|
||||
} finally {
|
||||
try {
|
||||
writer.close();
|
||||
zipfs.close();
|
||||
} catch (IOException e) {
|
||||
logger.debug(e.getLocalizedMessage());
|
||||
logger.debug("Ops!",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void reOpenDoc(){
|
||||
try {
|
||||
XComponent doc = loader.loadComponentFromURL(url, "_default", 0, new PropertyValue[0]);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Failed to open the document");
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
public void closeDocument() {
|
||||
if (context != null) {
|
||||
executedispatch("CloseDoc", new PropertyValue[0]);
|
||||
} else {
|
||||
logger.debug("Can't close document. No context.");
|
||||
}
|
||||
}
|
||||
|
||||
public void reloadDocument() {
|
||||
if (context != null) {
|
||||
executedispatch("Reload", new PropertyValue[0]);
|
||||
} else {
|
||||
logger.debug("Can't reload document. No context.");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSupported(Object object, String service) {
|
||||
XServiceInfo info = UnoRuntime.queryInterface(XServiceInfo.class, object);
|
||||
if (info == null) {
|
||||
return false;
|
||||
}
|
||||
return info.supportsService(service);
|
||||
}
|
||||
|
||||
private boolean executedispatch( String cmd, PropertyValue[] props) {
|
||||
XDispatchHelper helper = createInstance(XDispatchHelper.class, "com.sun.star.frame.DispatchHelper");
|
||||
if (helper == null) {
|
||||
logger.debug("Could not create dispatch helper for command " + cmd);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Object oDesktop = context.getServiceManager().createInstanceWithContext("com.sun.star.frame.Desktop", context);
|
||||
XDesktop xDesktop = UnoRuntime.queryInterface(XDesktop.class, oDesktop);
|
||||
XDispatchProvider provider = UnoRuntime.queryInterface(XDispatchProvider.class, xDesktop.getCurrentFrame());
|
||||
helper.executeDispatch(provider, ".uno:" + cmd, "", 0, props);
|
||||
return true;
|
||||
} catch (java.lang.Exception e) {
|
||||
logger.debug("Could not dispatch '" + cmd + "':\n " + e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private <T> T createInstance(Class<T> aType, String serviceName) {
|
||||
if ((context == null)) {
|
||||
logger.debug("No libreoffice context. Cant create instance of " + aType.toString());
|
||||
return null;
|
||||
}
|
||||
T interfaceObj = null;
|
||||
try {
|
||||
Object o = context.getServiceManager().createInstanceWithContext(serviceName, context);
|
||||
interfaceObj = UnoRuntime.queryInterface(aType, o);
|
||||
} catch (Exception e) {
|
||||
logger.debug("Couldn't create interface for '" + serviceName + "': " + e);
|
||||
}
|
||||
return interfaceObj;
|
||||
}
|
||||
|
||||
public boolean compareWithBackup(Settings backedUpSettings) {
|
||||
return SettingsComparator.isEqual(getCurrentSettings(), backedUpSettings);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package pro.litvinovg.docsettings.exceptions;
|
||||
|
||||
public class MalformedXmlException extends Exception{
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MalformedXmlException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
202
src/main/java/pro/litvinovg/docsettings/gui/BackupPanel.java
Normal file
202
src/main/java/pro/litvinovg/docsettings/gui/BackupPanel.java
Normal file
|
@ -0,0 +1,202 @@
|
|||
package pro.litvinovg.docsettings.gui;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.DefaultListSelectionModel;
|
||||
import javax.swing.GroupLayout;
|
||||
import javax.swing.GroupLayout.Alignment;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.LayoutStyle.ComponentPlacement;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import pro.litvinovg.docsettings.ExtensionConfig;
|
||||
import pro.litvinovg.docsettings.Localizer;
|
||||
import pro.litvinovg.docsettings.document.ODFDocument;
|
||||
import pro.litvinovg.docsettings.settings.Backups;
|
||||
import pro.litvinovg.docsettings.settings.Settings;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
public class BackupPanel extends JPanel {
|
||||
|
||||
private ExtensionConfig config;
|
||||
private ODFDocument document;
|
||||
private Backups backups;
|
||||
private JButton btn_close;
|
||||
private JButton btn_restore;
|
||||
private JButton btn_create;
|
||||
private JButton btn_delete;
|
||||
private JList lst_backups;
|
||||
private DefaultListModel backupListModel;
|
||||
private static final Logger logger = LoggerFactory.getLogger(BackupPanel.class);
|
||||
private JCheckBox cb_stick_latest_backup;
|
||||
private JFrame frame;
|
||||
|
||||
|
||||
public BackupPanel(JFrame frame, ODFDocument document, Backups backups) {
|
||||
this.frame = frame;
|
||||
this.backups = backups;
|
||||
this.config = ExtensionConfig.getInstance();
|
||||
this.document = document;
|
||||
initComponents();
|
||||
initEvents();
|
||||
}
|
||||
|
||||
private void initEvents() {
|
||||
onCreateButtonClick();
|
||||
onDeleteButtonClick();
|
||||
onRestoreButtonClick();
|
||||
onCloseButtonClick();
|
||||
onCheckBoxClick();
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
|
||||
backupListModel = new DefaultListModel();
|
||||
populateList();
|
||||
lst_backups = new JList(backupListModel);
|
||||
lst_backups.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
|
||||
|
||||
JLabel lb_backups = new JLabel(Localizer.get("backup_panel_description"));
|
||||
|
||||
btn_delete = new JButton(Localizer.get("delete_backup_button"));
|
||||
btn_create = new JButton(Localizer.get("create_backup_button"));
|
||||
btn_restore = new JButton(Localizer.get("restore_button"));
|
||||
btn_close = new JButton(Localizer.get("close_window_button"));
|
||||
|
||||
cb_stick_latest_backup = new JCheckBox(Localizer.get("stick_latest_backup_cb_label"));
|
||||
cb_stick_latest_backup.setSelected(config.getAutoRestore());
|
||||
cb_stick_latest_backup.setVerticalAlignment(SwingConstants.TOP);
|
||||
|
||||
GroupLayout groupLayout = new GroupLayout(this);
|
||||
groupLayout.setHorizontalGroup(
|
||||
groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addGap(43)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
|
||||
.addComponent(lb_backups, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(lst_backups, GroupLayout.PREFERRED_SIZE, 354, GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(26)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
|
||||
.addComponent(cb_stick_latest_backup, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btn_close, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btn_delete, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 269, Short.MAX_VALUE)
|
||||
.addComponent(btn_create, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btn_restore, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||
.addContainerGap(288, Short.MAX_VALUE))
|
||||
);
|
||||
groupLayout.setVerticalGroup(
|
||||
groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(lb_backups, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(14)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addComponent(lst_backups, GroupLayout.PREFERRED_SIZE, 384, GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(btn_delete)
|
||||
.addGap(18)
|
||||
.addComponent(btn_create)
|
||||
.addGap(18)
|
||||
.addComponent(btn_restore)
|
||||
.addGap(33)
|
||||
.addComponent(cb_stick_latest_backup, GroupLayout.PREFERRED_SIZE, 83, GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(132)
|
||||
.addComponent(btn_close)))
|
||||
.addContainerGap(74, Short.MAX_VALUE))
|
||||
);
|
||||
setLayout(groupLayout);
|
||||
}
|
||||
|
||||
private void populateList() {
|
||||
backupListModel.clear();
|
||||
int i = 0;
|
||||
for(String date : backups.getBackupTimeLabels()) {
|
||||
backupListModel.add(i,date);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private void onCreateButtonClick() {
|
||||
btn_create.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if (document == null) {
|
||||
return;
|
||||
}
|
||||
backups.create(document.getCurrentSettings());
|
||||
document.writeBackups(backups);
|
||||
populateList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onDeleteButtonClick() {
|
||||
btn_delete.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if (lst_backups.isSelectionEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (document == null) {
|
||||
return;
|
||||
}
|
||||
String selected = (String) lst_backups.getSelectedValue();
|
||||
backups.removeByDateTimeLabel(selected);
|
||||
document.writeBackups(backups);
|
||||
populateList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onRestoreButtonClick() {
|
||||
btn_restore.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if (lst_backups.isSelectionEmpty()) {
|
||||
JOptionPane.showMessageDialog(frame, Localizer.get("no_backup_selected"));
|
||||
return;
|
||||
}
|
||||
if (document == null) {
|
||||
JOptionPane.showMessageDialog(frame, Localizer.get("error_document_not_found"));
|
||||
return;
|
||||
}
|
||||
String selected = (String) lst_backups.getSelectedValue();
|
||||
Settings backup;
|
||||
try {
|
||||
backup = backups.getByDateTimeLabel(selected);
|
||||
document.restoreSettings(backup);
|
||||
MainWindow.getSingleFrame().setVisible(false);
|
||||
MainWindow.getSingleFrame().dispose();
|
||||
} catch (Exception e) {
|
||||
logger.debug("Restore failed", e);
|
||||
JOptionPane.showMessageDialog(frame, Localizer.get("restore_failed \n" + e.getLocalizedMessage()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onCloseButtonClick() {
|
||||
btn_close.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
MainWindow.getSingleFrame().setVisible(false);
|
||||
MainWindow.getSingleFrame().dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onCheckBoxClick() {
|
||||
cb_stick_latest_backup.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
config.setAutoRestore(cb_stick_latest_backup.isSelected());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package pro.litvinovg.docsettings.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.EventQueue;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
public class ChangedSettings extends JFrame {
|
||||
|
||||
private JPanel contentPane;
|
||||
|
||||
/**
|
||||
* Launch the application.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
ChangedSettings frame = new ChangedSettings();
|
||||
frame.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the frame.
|
||||
*/
|
||||
public ChangedSettings() {
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setBounds(100, 100, 450, 300);
|
||||
contentPane = new JPanel();
|
||||
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
contentPane.setLayout(new BorderLayout(0, 0));
|
||||
setContentPane(contentPane);
|
||||
}
|
||||
|
||||
}
|
123
src/main/java/pro/litvinovg/docsettings/gui/MainWindow.java
Normal file
123
src/main/java/pro/litvinovg/docsettings/gui/MainWindow.java
Normal file
|
@ -0,0 +1,123 @@
|
|||
package pro.litvinovg.docsettings.gui;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import java.awt.GridLayout;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.star.uno.XComponentContext;
|
||||
|
||||
import pro.litvinovg.docsettings.DialogHelper;
|
||||
import pro.litvinovg.docsettings.DocSettingsExtension;
|
||||
import pro.litvinovg.docsettings.ExtensionConfig;
|
||||
import pro.litvinovg.docsettings.Localizer;
|
||||
import pro.litvinovg.docsettings.document.ODFDocument;
|
||||
import pro.litvinovg.docsettings.settings.Backups;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.GroupLayout;
|
||||
import javax.swing.GroupLayout.Alignment;
|
||||
|
||||
import javax.swing.JList;
|
||||
|
||||
public class MainWindow extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static JFrame frame = null;
|
||||
private Localizer localizer;
|
||||
private ODFDocument document;
|
||||
private Backups backups;
|
||||
private static final Logger logger = LoggerFactory.getLogger(MainWindow.class);
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
MainWindow window = new MainWindow();
|
||||
frame = window;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void runGUI(XComponentContext context) {
|
||||
|
||||
if (frame != null) {
|
||||
frame.dispose();
|
||||
}
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Throwable e) {
|
||||
String message = e.getLocalizedMessage();
|
||||
JOptionPane.showMessageDialog(frame, message);
|
||||
}
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
MainWindow window = new MainWindow(context);
|
||||
frame = window;
|
||||
} catch (Throwable e) {
|
||||
DialogHelper.showErrorMessage(context, null, e.getLocalizedMessage());
|
||||
logger.debug("Ops", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static JFrame getSingleFrame() {
|
||||
return frame;
|
||||
}
|
||||
|
||||
public MainWindow() {
|
||||
backups = new Backups();
|
||||
initialize();
|
||||
}
|
||||
|
||||
public MainWindow(XComponentContext context) throws Exception {
|
||||
document = new ODFDocument(context);
|
||||
backups = new Backups();
|
||||
document.readSettings();
|
||||
document.readBackups(backups);
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the contents of the frame.
|
||||
*/
|
||||
private void initialize() {
|
||||
setIconImage(Toolkit.getDefaultToolkit().getImage(MainWindow.class.getResource("/pro/litvinovg/docsettings/resources/icon.png")));
|
||||
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
getContentPane().setLayout(new GridLayout(1, 0, 0, 0));
|
||||
localizer = Localizer.getInstance();
|
||||
this.setBounds(100, 100, 750, 500);
|
||||
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
this.setVisible(true);
|
||||
|
||||
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
|
||||
getContentPane().add(tabbedPane);
|
||||
|
||||
JPanel backupPanel = new BackupPanel(this, document, backups);
|
||||
tabbedPane.addTab(localizer.getTranslation("backups_tab_name"), null, backupPanel, null);
|
||||
|
||||
//JPanel settingsPanel = new SettingsPanel(this, document);
|
||||
//tabbedPane.addTab(localizer.getTranslation("settings_tab_name"), null, settingsPanel, null);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package pro.litvinovg.docsettings.gui;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import pro.litvinovg.docsettings.ExtensionConfig;
|
||||
import pro.litvinovg.docsettings.Localizer;
|
||||
import pro.litvinovg.docsettings.document.ODFDocument;
|
||||
import java.awt.GridLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
public class SettingsPanel extends JPanel {
|
||||
|
||||
private ExtensionConfig config;
|
||||
private Localizer localizer;
|
||||
private ODFDocument document;
|
||||
private JFrame frame;
|
||||
|
||||
public SettingsPanel(JFrame mainWindow, ODFDocument document) {
|
||||
this.frame = mainWindow;
|
||||
this.document = document;
|
||||
this.config = ExtensionConfig.getInstance();
|
||||
this.localizer = Localizer.getInstance();
|
||||
setLayout(new GridLayout(1, 0, 0, 0));
|
||||
initComponents();
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
close_window_button = Close
|
||||
restore_button = Restore from backup
|
||||
create_backup_button = Create backup
|
||||
delete_backup_button = Delete backup
|
||||
settings_tab_name = Settings
|
||||
backups_tab_name = Backups
|
||||
backup_panel_description = Manage document settings backups
|
||||
no_timestamp_found_error = No backup dates found
|
||||
stick_latest_backup_cb_label = Block settings
|
||||
no_backup_selected = Select backup and try again
|
||||
error_document_not_found = Document not found.
|
||||
error_document_is_not_saved = Document is not saved. Save document before proceeding.
|
||||
error_document_is_ro = Document opened in read only mode.
|
||||
error_document_is_null = Document not found
|
||||
error_document_type_is_not_supported = Document type is not supported.
|
|
@ -0,0 +1,15 @@
|
|||
close_window_button = Закрыть
|
||||
restore_button = Восстановить из резервной копии
|
||||
create_backup_button = Создать резервную копию
|
||||
delete_backup_button = Удалить резервную копию
|
||||
settings_tab_name = Настройки
|
||||
backups_tab_name = Резервные копии
|
||||
backup_panel_description = Управление резервными копиями настроек документов
|
||||
no_timestamp_found_error = Не найдено дат резервных копий
|
||||
stick_latest_backup_cb_label = Заблокировать изменение настроек
|
||||
no_backup_selected = Выберите резервную копию и попробуйте снова
|
||||
error_document_not_found = Ошибка. Документ не найден.
|
||||
error_document_is_not_saved = Документ не сохранен. Сохраните документ и попробуйте снова.
|
||||
error_document_is_ro = Документ открыт в режиме только для чтения.
|
||||
error_document_is_null = Ошибка. Документ не найден.
|
||||
error_document_type_is_not_supported = Тип документа не поддерживается. Сохраните документ в формате ODT.
|
BIN
src/main/java/pro/litvinovg/docsettings/resources/icon.png
Normal file
BIN
src/main/java/pro/litvinovg/docsettings/resources/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
445
src/main/java/pro/litvinovg/docsettings/settings/Backups.java
Normal file
445
src/main/java/pro/litvinovg/docsettings/settings/Backups.java
Normal file
|
@ -0,0 +1,445 @@
|
|||
package pro.litvinovg.docsettings.settings;
|
||||
|
||||
import static pro.litvinovg.docsettings.settings.StorageUtils.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpression;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.sun.star.beans.IllegalTypeException;
|
||||
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.lang.IllegalArgumentException;
|
||||
import com.sun.star.lang.WrappedTargetException;
|
||||
import com.sun.star.uno.UnoRuntime;
|
||||
|
||||
import pro.litvinovg.docsettings.exceptions.MalformedXmlException;
|
||||
|
||||
public class Backups {
|
||||
|
||||
private static final short REMOVABLE_PROPERTY = 128;
|
||||
private static final int OO_XML_MAX_LENGTH = 65535;
|
||||
private static final Logger logger = LoggerFactory.getLogger(Backups.class);
|
||||
private static final String BACKUP_NAME_PREFIX = "SerializedSettings-";
|
||||
private TreeMap<Long,Settings> backups = null;
|
||||
|
||||
public Backups() {
|
||||
backups = new TreeMap<Long,Settings>();
|
||||
}
|
||||
|
||||
public void add(Long unixTimeStamp, Settings backup) {
|
||||
backups.put(unixTimeStamp, backup);
|
||||
}
|
||||
public void clear() {
|
||||
backups.clear();
|
||||
}
|
||||
public boolean isEmpty() {
|
||||
return backups.isEmpty();
|
||||
}
|
||||
|
||||
public void create(Settings currentSettings) {
|
||||
backups.put( getUnixTime(), currentSettings);
|
||||
}
|
||||
|
||||
public Settings getBackupByTimeStamp(Long timeStamp) {
|
||||
return backups.get(timeStamp);
|
||||
}
|
||||
|
||||
public Settings getLatest() {
|
||||
return backups.lastEntry().getValue();
|
||||
}
|
||||
|
||||
public Set<Long> getTimeStamps() {
|
||||
return backups.keySet();
|
||||
}
|
||||
|
||||
public void readBackupsFromMetadata(XPropertyContainer userDefinedProps) {
|
||||
clear();
|
||||
TreeMap<Long, Map<Long, String>> backupMap = getBackupMap(userDefinedProps);
|
||||
Map<Long,String> serializedBackups = combineBackupStrings(backupMap);
|
||||
for (Entry<Long, String> entry : serializedBackups.entrySet()) {
|
||||
Long unixTimeStamp = entry.getKey();
|
||||
String backupString = entry.getValue();
|
||||
if (!backupString.isEmpty()) {
|
||||
backupString = decodeBase64(backupString);
|
||||
readBackup(unixTimeStamp, backupString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBackupsToMetadata(XPropertyContainer userDefinedProps) {
|
||||
cleanBackupMetadata(userDefinedProps);
|
||||
for (Entry<Long, Settings> backup : backups.entrySet()) {
|
||||
try {
|
||||
addBackupEntries( userDefinedProps, backup);
|
||||
} catch (MalformedXmlException | ParserConfigurationException | TransformerException e) {
|
||||
logger.debug("Ops", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanBackupMetadata(XPropertyContainer userDefinedProps) {
|
||||
XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, userDefinedProps);
|
||||
XPropertySetInfo propSetInfo = propertySet.getPropertySetInfo();
|
||||
Property[] props = propSetInfo.getProperties();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
try {
|
||||
String name = props[i].Name;
|
||||
if (name.startsWith(BACKUP_NAME_PREFIX)) {
|
||||
userDefinedProps.removeProperty(name);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.debug("Ops", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addBackupEntries(XPropertyContainer userDefinedProps, Entry<Long, Settings> backup) throws MalformedXmlException, ParserConfigurationException, TransformerException {
|
||||
String backupString = serializeSettingsXML(backup.getValue());
|
||||
backupString = encodeBase64(backupString);
|
||||
List<String> parts = splitByOOMaxLength(backupString);
|
||||
for (int i = 0; i < parts.size();i++) {
|
||||
String part = parts.get(i);
|
||||
String name = formatBackupMetaName(backup.getKey(),i);
|
||||
try {
|
||||
userDefinedProps.addProperty(name, REMOVABLE_PROPERTY, part);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.debug("Ops", e);
|
||||
} catch (PropertyExistException e) {
|
||||
//it is ok
|
||||
logger.debug("Ops", e);
|
||||
} catch (IllegalTypeException e) {
|
||||
logger.debug("Ops", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void readBackup(Long unixTimeStamp, String backupString) {
|
||||
Document backupDoc;
|
||||
try {
|
||||
backupDoc = getDocFromString(backupString);
|
||||
Element configSettings = (Element) getSettingsElement(backupDoc);
|
||||
NodeList settingNodes = configSettings.getChildNodes();
|
||||
Settings backup = readSettingsFromNodeList(settingNodes);
|
||||
add(unixTimeStamp,backup);
|
||||
} catch (ParserConfigurationException | SAXException | IOException e) {
|
||||
logger.debug("Ops", e);
|
||||
} catch (Exception e) {
|
||||
logger.debug("Ops", e);
|
||||
}
|
||||
}
|
||||
|
||||
private TreeMap<Long, Map<Long, String>> getBackupMap(XPropertyContainer userDefinedProps) {
|
||||
TreeMap<Long, Map<Long, String>> backupMap = new TreeMap<Long,Map<Long,String>>();
|
||||
|
||||
XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, userDefinedProps);
|
||||
XPropertySetInfo propSetInfo = propertySet.getPropertySetInfo();
|
||||
Property[] props = propSetInfo.getProperties();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
try {
|
||||
Property prop = props[i];
|
||||
String name = prop.Name;
|
||||
if (name.startsWith(BACKUP_NAME_PREFIX)) {
|
||||
Long timeStamp = Long.parseLong(getTimeStampFromString(name));
|
||||
Long order = Long.parseLong(getOrderFromString(name));
|
||||
String stringPart = propertySet.getPropertyValue(prop.Name).toString();
|
||||
Map<Long, String> backupParts = null;
|
||||
if (backupMap.containsKey(timeStamp)) {
|
||||
backupParts = backupMap.get(timeStamp);
|
||||
} else {
|
||||
backupParts = new TreeMap<Long,String>();
|
||||
backupMap.put(timeStamp, backupParts);
|
||||
}
|
||||
backupParts.put(order, stringPart);
|
||||
}
|
||||
//logger.debug("Prop name "+ prop.Name + " Prop value " + propertySet.getPropertyValue(prop.Name));
|
||||
} catch (UnknownPropertyException | WrappedTargetException e) {
|
||||
logger.debug("Ops", e);
|
||||
}
|
||||
}
|
||||
return backupMap;
|
||||
}
|
||||
|
||||
public void readBackupsFromXML(String metaContent) {
|
||||
clear();
|
||||
try {
|
||||
Document doc = getDocFromString(metaContent);
|
||||
Map<Long,String> serializedBackups = getSerializedBackups(doc);
|
||||
for (Entry<Long, String> entry : serializedBackups.entrySet()) {
|
||||
Long unixTimeStamp = entry.getKey();
|
||||
String backupString = entry.getValue();
|
||||
if (!backupString.isEmpty()) {
|
||||
backupString = decodeBase64(backupString);
|
||||
Document backupDoc = getDocFromString(backupString);
|
||||
Element configSettings = (Element) getSettingsElement(backupDoc);
|
||||
NodeList settingNodes = configSettings.getChildNodes();
|
||||
Settings backup = readSettingsFromNodeList(settingNodes);
|
||||
add(unixTimeStamp,backup);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.debug(e.getMessage());
|
||||
logger.debug("Ops!",e);
|
||||
}
|
||||
}
|
||||
|
||||
private Settings readSettingsFromNodeList(NodeList settingNodes) throws MalformedXmlException {
|
||||
Settings settings = new Settings();
|
||||
for (int i = 0; i < settingNodes.getLength(); i++) {
|
||||
Node settingNode = settingNodes.item(i);
|
||||
ODFSetting setting = SettingFactory.create(settingNode);
|
||||
settings.add(setting);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
public String getNewMetaContent(String metaContent) {
|
||||
String cleanedMeta = getCleanedMetaContent(metaContent);
|
||||
String newMetaContent = "";
|
||||
try {
|
||||
Document doc = getDocFromString(cleanedMeta);
|
||||
for (Entry<Long, Settings> backup : backups.entrySet()) {
|
||||
addXMLBackupEntries( doc, backup.getKey(), backup.getValue());
|
||||
}
|
||||
newMetaContent = serializeDoc(doc);
|
||||
} catch (Exception e) {
|
||||
logger.debug(e.getMessage());
|
||||
logger.debug("Ops!",e);
|
||||
}
|
||||
return newMetaContent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void addXMLBackupEntries(Document doc, Long timeStamp, Settings settings) throws MalformedXmlException, ParserConfigurationException, TransformerException {
|
||||
String backupString = serializeSettingsXML(settings);
|
||||
backupString = encodeBase64(backupString);
|
||||
List<String> parts = splitByOOMaxLength(backupString);
|
||||
for (int i = 0; i < parts.size();i++) {
|
||||
String part = parts.get(i);
|
||||
addMetadataEntry(doc,timeStamp,part, i);
|
||||
}
|
||||
}
|
||||
|
||||
private void addMetadataEntry(Document doc, Long timeStamp, String string, int i) throws MalformedXmlException {
|
||||
Element element = doc.createElement("meta:user-defined");
|
||||
String name = formatBackupMetaName(timeStamp,i);
|
||||
element.setAttribute("meta:name", name);
|
||||
element.setTextContent(string);
|
||||
Node metaRoot = getMetaRootElement(doc);
|
||||
metaRoot.appendChild(element);
|
||||
}
|
||||
|
||||
private String formatBackupMetaName(Long timeStamp, int i) {
|
||||
String result = BACKUP_NAME_PREFIX + timeStamp.toString() + "-" + i;
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<String> splitByOOMaxLength(String text) {
|
||||
List<String> array = new ArrayList<String>();
|
||||
int index = 0;
|
||||
while (index < text.length()) {
|
||||
array.add(text.substring(index, Math.min(index + OO_XML_MAX_LENGTH, text.length())));
|
||||
index += OO_XML_MAX_LENGTH;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private String serializeSettingsXML(Settings settings) throws ParserConfigurationException, TransformerException {
|
||||
Document doc = createNewDoc();
|
||||
Element root = doc.createElementNS("urn:oasis:names:tc:opendocument:xmlns:config:1.0","config:config-item-set");
|
||||
root.setAttribute("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0");
|
||||
root.setAttribute("xmlns:ooo", "http://openoffice.org/2004/office");
|
||||
root.setAttribute("config:name", "ooo:configuration-settings");
|
||||
doc.appendChild(root);
|
||||
appendSettingNodesToDoc(settings, doc, root);
|
||||
String result = serializeDoc(doc);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private String getCleanedMetaContent(String metaContent) {
|
||||
String cleanedMetaContent = "";
|
||||
try {
|
||||
Document doc = getDocFromString(metaContent);
|
||||
NodeList nodes = getBackupEntries(doc);
|
||||
removeNodes(nodes);
|
||||
cleanedMetaContent = serializeDoc(doc);
|
||||
} catch (Exception e) {
|
||||
logger.debug(e.getMessage());
|
||||
logger.debug("Ops!",e);
|
||||
}
|
||||
return cleanedMetaContent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Map<Long,String> getSerializedBackups(Document doc) throws MalformedXmlException {
|
||||
NodeList nodes = getBackupEntries(doc);
|
||||
TreeMap<Long, Map<Long, String>> backupStringMap = sortBackupStrings(nodes);
|
||||
Map<Long,String> result = combineBackupStrings(backupStringMap);
|
||||
return result;
|
||||
}
|
||||
|
||||
private NodeList getBackupEntries(Document doc) throws MalformedXmlException {
|
||||
XPathFactory xPathfactory = XPathFactory.newInstance();
|
||||
XPath xpath = xPathfactory.newXPath();
|
||||
XPathExpression expr;
|
||||
NodeList nodes;
|
||||
try {
|
||||
expr = xpath.compile("//*[local-name() ='user-defined'][@*[local-name() ='name' and starts-with(.,'"+ BACKUP_NAME_PREFIX + "')]]");
|
||||
nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
|
||||
} catch (XPathExpressionException e) {
|
||||
logger.debug(e.getLocalizedMessage());
|
||||
throw new MalformedXmlException("Xpath expression failed while looking for backup entries");
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private Map<Long, String> combineBackupStrings(TreeMap<Long, Map<Long, String>> backupMap) {
|
||||
TreeMap<Long, String> result = new TreeMap<Long, String>();
|
||||
for(Map.Entry<Long, Map<Long,String>> entry: backupMap.entrySet()) {
|
||||
Long timeStamp = entry.getKey();
|
||||
Map<Long, String> parts = entry.getValue();
|
||||
String combinedString = "";
|
||||
for(Map.Entry<Long, String> part: parts.entrySet()) {
|
||||
String serlializedString = part.getValue();
|
||||
combinedString += serlializedString;
|
||||
}
|
||||
result.put(timeStamp, combinedString);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private TreeMap<Long, Map<Long, String>> sortBackupStrings(NodeList nodes) throws MalformedXmlException {
|
||||
TreeMap<Long, Map<Long, String>> backupMap = new TreeMap<Long,Map<Long,String>>();
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Node node = nodes.item(i);
|
||||
Long timeStamp = getTimeStampFromNode(node);
|
||||
Long order = getOrderFromNode(node);
|
||||
String stringPart = node.getTextContent();
|
||||
Map<Long, String> backupParts = null;
|
||||
if (backupMap.containsKey(timeStamp)) {
|
||||
backupParts = backupMap.get(timeStamp);
|
||||
} else {
|
||||
backupParts = new TreeMap<Long,String>();
|
||||
backupMap.put(timeStamp, backupParts);
|
||||
}
|
||||
backupParts.put(order, stringPart);
|
||||
}
|
||||
return backupMap;
|
||||
}
|
||||
|
||||
private Long getTimeStampFromNode(Node node) throws MalformedXmlException {
|
||||
String name = node.getAttributes().getNamedItem("meta:name").getNodeValue();
|
||||
String ts = getTimeStampFromString(name);
|
||||
Long timeStamp = null;
|
||||
try {
|
||||
timeStamp = Long.parseLong(ts);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new MalformedXmlException("timestamp not found for metadata backup entry " + name);
|
||||
}
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
private String getTimeStampFromString(String name) {
|
||||
return name.replaceAll(BACKUP_NAME_PREFIX, "").replaceAll("-[0-9]$","");
|
||||
}
|
||||
|
||||
private Long getOrderFromNode(Node node) throws MalformedXmlException {
|
||||
String name = node.getAttributes().getNamedItem("meta:name").getNodeValue();
|
||||
String or = getOrderFromString(name);
|
||||
Long order;
|
||||
try {
|
||||
order = Long.parseLong(or);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new MalformedXmlException("order not found for metadata backup entry " + name);
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
private String getOrderFromString(String name) {
|
||||
return name.replaceAll(BACKUP_NAME_PREFIX + "[0-9]+-", "");
|
||||
}
|
||||
|
||||
private long getUnixTime() {
|
||||
return System.currentTimeMillis() / 1000L;
|
||||
}
|
||||
|
||||
public String[] getBackupTimeLabels() {
|
||||
String[] timeLabels = new String[backups.size()];
|
||||
int i = 0;
|
||||
for(Long backupTime: backups.keySet()) {
|
||||
timeLabels[i] = getDateTimeLabelsFromUnix(backupTime);
|
||||
i++;
|
||||
}
|
||||
return timeLabels;
|
||||
}
|
||||
|
||||
private String getDateTimeLabelsFromUnix(Long timeStamp){
|
||||
ZoneId zoneId = TimeZone.getDefault().toZoneId();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");
|
||||
final Instant instant = Instant.ofEpochSecond(timeStamp);
|
||||
LocalDateTime time = LocalDateTime.ofInstant(instant, zoneId);
|
||||
return formatter.format(time);
|
||||
}
|
||||
|
||||
private Long getUnixFromDateTimeLabels(String formattedTime){
|
||||
ZoneId zoneId = TimeZone.getDefault().toZoneId();
|
||||
DateTimeFormatter parseFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");
|
||||
LocalDateTime time = LocalDateTime.parse(formattedTime, parseFormat);
|
||||
return time.atZone(zoneId).toEpochSecond();
|
||||
}
|
||||
|
||||
public void removeByDateTimeLabel(String dateTimeLabel) {
|
||||
if (dateTimeLabel == null || dateTimeLabel.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Long unix = getUnixFromDateTimeLabels(dateTimeLabel);
|
||||
backups.remove(unix);
|
||||
}
|
||||
|
||||
public Settings getByDateTimeLabel(String dateTimeLabel) throws Exception {
|
||||
if (dateTimeLabel == null || dateTimeLabel.isEmpty()) {
|
||||
throw new Exception("date time not found");
|
||||
}
|
||||
Long unix = getUnixFromDateTimeLabels(dateTimeLabel);
|
||||
Settings result = backups.get(unix);
|
||||
if (result == null) {
|
||||
throw new Exception("backup not found");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package pro.litvinovg.docsettings.settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ComparatorResults {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ComparatorResults.class);
|
||||
|
||||
private List<ODFSetting> removedSettings = new ArrayList<ODFSetting>();
|
||||
private List<ODFSetting> newSetting = new ArrayList<ODFSetting>();
|
||||
private Map<ODFSetting,ODFSetting> changedSettings = new HashMap<ODFSetting,ODFSetting>();
|
||||
|
||||
public boolean hasChanges() {
|
||||
return removedSettings.isEmpty() && newSetting.isEmpty() && changedSettings.isEmpty();
|
||||
}
|
||||
|
||||
public void addRemovedProperty(ODFSetting setting){
|
||||
removedSettings.add(setting);
|
||||
}
|
||||
|
||||
public void addNewProperty(ODFSetting setting){
|
||||
newSetting.add(setting);
|
||||
}
|
||||
|
||||
public void addChangedProperty(ODFSetting oldSetting,ODFSetting newSetting){
|
||||
changedSettings.put(oldSetting, newSetting);
|
||||
}
|
||||
|
||||
public List<ODFSetting> getRemovedProperties() {
|
||||
return removedSettings;
|
||||
}
|
||||
|
||||
public List<ODFSetting> getAddedProperties() {
|
||||
return newSetting;
|
||||
}
|
||||
|
||||
public Map<ODFSetting, ODFSetting> getChangedProperties() {
|
||||
return changedSettings;
|
||||
}
|
||||
|
||||
public void log() {
|
||||
logger.info("New settings:");
|
||||
for (Iterator iterator = newSetting.iterator(); iterator.hasNext();) {
|
||||
ODFSetting odfSetting = (ODFSetting) iterator.next();
|
||||
logger.debug(odfSetting.getName());
|
||||
}
|
||||
logger.info("Removed settings:");
|
||||
for (Iterator iterator = removedSettings.iterator(); iterator.hasNext();) {
|
||||
ODFSetting odfSetting = (ODFSetting) iterator.next();
|
||||
logger.info(odfSetting.getName());
|
||||
}
|
||||
logger.info("Changed settings:");
|
||||
for (Entry<ODFSetting, ODFSetting> entry : changedSettings.entrySet()) {
|
||||
logger.info(entry.getKey().getName() + "\nChanged from "+ entry.getKey().getValue() + " to " + entry.getValue().getValue() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package pro.litvinovg.docsettings.settings;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
public interface ODFSetting {
|
||||
public String getName();
|
||||
public String getValue();
|
||||
public String getType();
|
||||
public void addToDocumentElement(Document doc, Node root);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package pro.litvinovg.docsettings.settings;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.star.uno.XComponentContext;
|
||||
|
||||
import pro.litvinovg.docsettings.DialogHelper;
|
||||
|
||||
public class ODFSettings {
|
||||
|
||||
private XComponentContext context;
|
||||
private static final Logger logger = LoggerFactory.getLogger(ODFSettings.class);
|
||||
|
||||
public ODFSettings(XComponentContext context ) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void printText(String text) {
|
||||
DialogHelper.showErrorMessage(context, null, text);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package pro.litvinovg.docsettings.settings;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import pro.litvinovg.docsettings.exceptions.MalformedXmlException;
|
||||
|
||||
import static pro.litvinovg.docsettings.settings.StorageUtils.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpression;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import pro.litvinovg.docsettings.exceptions.MalformedXmlException;
|
||||
|
||||
public class SettingFactory {
|
||||
private static final String TYPE_INT = "int";
|
||||
private static final String TYPE_BASE64_BINARY = "base64Binary";
|
||||
private static final String TYPE_STRING = "string";
|
||||
private static final String TYPE_SHORT = "short";
|
||||
private static final String TYPE_BOOLEAN = "boolean";
|
||||
private static final Logger logger = LoggerFactory.getLogger(SettingFactory.class);
|
||||
|
||||
public static ODFSetting create(Node node) throws MalformedXmlException {
|
||||
Node typeNode = node.getAttributes().getNamedItem("config:type");
|
||||
if (typeNode == null) {
|
||||
logger.debug("nodeType is null");
|
||||
throw new MalformedXmlException("Node " + node.getNodeName() + " config:type attribute not found.");
|
||||
}
|
||||
String type = typeNode.getNodeValue();
|
||||
if (type == null || type.isEmpty()) {
|
||||
logger.debug("node type value is null or empty");
|
||||
throw new MalformedXmlException("Node " + node.getNodeName() + " config:type attribute not found.");
|
||||
}
|
||||
if (TYPE_BOOLEAN.equals(type)||
|
||||
TYPE_SHORT.equals(type)||
|
||||
TYPE_STRING.equals(type)||
|
||||
TYPE_BASE64_BINARY.equals(type)||
|
||||
TYPE_INT.equals(type)) {
|
||||
return new SimpleSetting(node);
|
||||
}
|
||||
logger.debug("node type not recognized");
|
||||
throw new MalformedXmlException("Node " + node.getNodeName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package pro.litvinovg.docsettings.settings;
|
||||
|
||||
import static pro.litvinovg.docsettings.settings.StorageUtils.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
public class Settings {
|
||||
private static final Logger logger = LoggerFactory.getLogger(Settings.class);
|
||||
|
||||
|
||||
private List<ODFSetting> settings = null;
|
||||
|
||||
public Settings() {
|
||||
this.settings = new ArrayList<ODFSetting>();
|
||||
}
|
||||
|
||||
public void add(ODFSetting setting) {
|
||||
settings.add(setting);
|
||||
}
|
||||
|
||||
public void remove(int index) {
|
||||
settings.remove(index);
|
||||
}
|
||||
|
||||
public void remove(ODFSetting setting) {
|
||||
settings.remove(setting);
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return settings.size();
|
||||
}
|
||||
|
||||
public ODFSetting get(int num) {
|
||||
return settings.get(num);
|
||||
}
|
||||
|
||||
public ODFSetting getByName(String name) {
|
||||
for (Iterator iterator = settings.iterator(); iterator.hasNext();) {
|
||||
ODFSetting odfSetting = (ODFSetting) iterator.next();
|
||||
if (name.equals(odfSetting.getName())) {
|
||||
return odfSetting;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
settings.clear();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return settings.isEmpty();
|
||||
}
|
||||
|
||||
public String toSettingsContent(String content) throws Exception {
|
||||
Document doc = getDocFromString(content);
|
||||
Node settingsContainer = getSettingsElement(doc);
|
||||
NodeList settingNodes = settingsContainer.getChildNodes();
|
||||
removeNodes(settingNodes);
|
||||
appendSettingNodesToDoc(this, doc, settingsContainer);
|
||||
String newSettingsContent = serializeDoc(doc);
|
||||
return newSettingsContent;
|
||||
}
|
||||
|
||||
public void addAll(Settings inputSettings) {
|
||||
for (int i = 0; i < inputSettings.getSize(); i++) {
|
||||
this.add(inputSettings.get(i));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package pro.litvinovg.docsettings.settings;
|
||||
|
||||
public class SettingsComparator {
|
||||
|
||||
private static final String RSID = "Rsid";
|
||||
|
||||
public static boolean isEqual(Settings currentSettings, Settings backedUpSettings) {
|
||||
Settings newSettings = new Settings();
|
||||
newSettings.addAll(currentSettings);
|
||||
Settings oldSettings = new Settings();
|
||||
oldSettings.addAll(backedUpSettings);
|
||||
ComparatorResults results = compare(newSettings, oldSettings);
|
||||
if (results.hasChanges()) {
|
||||
results.log();
|
||||
}
|
||||
return !results.hasChanges();
|
||||
}
|
||||
|
||||
private static ComparatorResults compare(Settings newSettings, Settings oldSettings) {
|
||||
ComparatorResults results = new ComparatorResults();
|
||||
while (!newSettings.isEmpty()) {
|
||||
ODFSetting newSet = newSettings.get(0);
|
||||
ODFSetting oldSet = oldSettings.getByName(newSet.getName());
|
||||
if (oldSet == null) {
|
||||
results.addNewProperty(newSet);
|
||||
} else {
|
||||
if (!(newSet.getValue()).equals(oldSet.getValue()) && !isExcluded(newSet.getName())) {
|
||||
results.addChangedProperty(oldSet, newSet);
|
||||
}
|
||||
oldSettings.remove(oldSet);
|
||||
}
|
||||
newSettings.remove(newSet);
|
||||
}
|
||||
while (!oldSettings.isEmpty()) {
|
||||
ODFSetting oldSet = oldSettings.get(0);
|
||||
results.addRemovedProperty(oldSet);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static boolean isExcluded(String name) {
|
||||
if (name.equals(RSID)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package pro.litvinovg.docsettings.settings;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import pro.litvinovg.docsettings.exceptions.MalformedXmlException;
|
||||
|
||||
public class SimpleSetting implements ODFSetting {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SimpleSetting.class);
|
||||
protected String name;
|
||||
protected String value;
|
||||
protected String type;
|
||||
|
||||
public SimpleSetting(Node node) throws MalformedXmlException {
|
||||
this.name = getNodeName(node);
|
||||
this.value = node.getTextContent();
|
||||
this.type = node.getAttributes().getNamedItem("config:type").getNodeValue();
|
||||
}
|
||||
protected String getNodeName(Node node) throws MalformedXmlException {
|
||||
Node nameAttr = node.getAttributes().getNamedItem("config:name");
|
||||
if (nameAttr == null) {
|
||||
logger.debug("name attribute not found while creating simple property");
|
||||
throw new MalformedXmlException("Node " + node.getNodeName() + " config:name attribute not found.");
|
||||
}
|
||||
return nameAttr.getNodeValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
@Override
|
||||
public void addToDocumentElement(Document doc, Node rootElement) {
|
||||
Element element = doc.createElement("config:config-item");
|
||||
element.setAttribute("config:name", getName());
|
||||
element.setAttribute("config:type", getType());
|
||||
element.setTextContent(getValue());
|
||||
rootElement.appendChild(element);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package pro.litvinovg.docsettings.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Base64;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpression;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import pro.litvinovg.docsettings.exceptions.MalformedXmlException;
|
||||
|
||||
public class StorageUtils {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(StorageUtils.class);
|
||||
|
||||
public static Document getDocFromString(String xmlString) throws ParserConfigurationException, SAXException, IOException {
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
Document doc = db.parse(new InputSource(new StringReader(xmlString)));
|
||||
return doc;
|
||||
}
|
||||
|
||||
public static Document createNewDoc() throws ParserConfigurationException {
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
Document doc = db.newDocument();
|
||||
return doc;
|
||||
}
|
||||
|
||||
public static String serializeDoc(Document doc) throws TransformerException {
|
||||
StringWriter output = new StringWriter();
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
|
||||
transformer.transform(new DOMSource(doc), new StreamResult(output));
|
||||
String str = output.toString();
|
||||
return str;
|
||||
}
|
||||
|
||||
public static String printNode(Node node) throws TransformerException {
|
||||
StringWriter output = new StringWriter();
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
|
||||
transformer.transform(new DOMSource(node), new StreamResult(output));
|
||||
String str = output.toString();
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
public static String encodeBase64(String string) {
|
||||
return new String(Base64.getEncoder().encode(string.getBytes()));
|
||||
}
|
||||
|
||||
public static String decodeBase64(String serializedMetaSettings) {
|
||||
return new String(Base64.getDecoder().decode(serializedMetaSettings));
|
||||
}
|
||||
|
||||
public static void removeNodes(NodeList nodes) {
|
||||
for (int i = nodes.getLength()-1; i >= 0; i--) {
|
||||
Node node = nodes.item(i);
|
||||
node.getParentNode().removeChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
public static void appendSettingNodesToDoc(Settings settings, Document doc, Node root) {
|
||||
for(int i = 0; i< settings.getSize();i++) {
|
||||
ODFSetting setting = settings.get(i);
|
||||
setting.addToDocumentElement(doc,root);
|
||||
}
|
||||
}
|
||||
|
||||
public static Node getSettingsElement(Document doc) throws Exception {
|
||||
XPathFactory xPathfactory = XPathFactory.newInstance();
|
||||
XPath xpath = xPathfactory.newXPath();
|
||||
XPathExpression expr = xpath.compile("//*[local-name() ='config-item-set'][@*[local-name() ='name' and .='ooo:configuration-settings']]");
|
||||
NodeList configItems = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
|
||||
Node configSettings = configItems.item(0);
|
||||
if (configSettings == null) {
|
||||
throw new MalformedXmlException("No configuration settings element found");
|
||||
}
|
||||
return configSettings;
|
||||
}
|
||||
|
||||
public static Node getMetaRootElement(Document doc) throws MalformedXmlException {
|
||||
XPathFactory xPathfactory = XPathFactory.newInstance();
|
||||
XPath xpath = xPathfactory.newXPath();
|
||||
XPathExpression expr;
|
||||
NodeList nodes;
|
||||
try {
|
||||
expr = xpath.compile("//*[local-name() ='meta']");
|
||||
nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
|
||||
if (nodes.getLength() == 0 ) {
|
||||
throw new MalformedXmlException("Xpath expression failed while looking for main meta element");
|
||||
}
|
||||
} catch (XPathExpressionException e) {
|
||||
logger.debug(e.getLocalizedMessage());
|
||||
logger.debug("Ops!",e);
|
||||
throw new MalformedXmlException("Xpath expression failed while looking for main meta element");
|
||||
}
|
||||
Node result = nodes.item(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package pro.litvinovg.docsettings.exceptions;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class MalformedXmlExceptionTest {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package pro.litvinovg.docsettings.processor;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ODFSettingsTest {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
131
testFiles/settings-old.xml
Normal file
131
testFiles/settings-old.xml
Normal file
|
@ -0,0 +1,131 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<office:document-settings xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" office:version="1.3">
|
||||
<office:settings>
|
||||
<config:config-item-set config:name="ooo:view-settings">
|
||||
<config:config-item config:name="ViewAreaTop" config:type="long">0</config:config-item>
|
||||
<config:config-item config:name="ViewAreaLeft" config:type="long">0</config:config-item>
|
||||
<config:config-item config:name="ViewAreaWidth" config:type="long">21625</config:config-item>
|
||||
<config:config-item config:name="ViewAreaHeight" config:type="long">9213</config:config-item>
|
||||
<config:config-item config:name="ShowRedlineChanges" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="InBrowseMode" config:type="boolean">false</config:config-item>
|
||||
<config:config-item-map-indexed config:name="Views">
|
||||
<config:config-item-map-entry>
|
||||
<config:config-item config:name="ViewId" config:type="string">view2</config:config-item>
|
||||
<config:config-item config:name="ViewLeft" config:type="long">3401</config:config-item>
|
||||
<config:config-item config:name="ViewTop" config:type="long">2501</config:config-item>
|
||||
<config:config-item config:name="VisibleLeft" config:type="long">0</config:config-item>
|
||||
<config:config-item config:name="VisibleTop" config:type="long">0</config:config-item>
|
||||
<config:config-item config:name="VisibleRight" config:type="long">21624</config:config-item>
|
||||
<config:config-item config:name="VisibleBottom" config:type="long">9211</config:config-item>
|
||||
<config:config-item config:name="ZoomType" config:type="short">0</config:config-item>
|
||||
<config:config-item config:name="ViewLayoutColumns" config:type="short">1</config:config-item>
|
||||
<config:config-item config:name="ViewLayoutBookMode" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ZoomFactor" config:type="short">214</config:config-item>
|
||||
<config:config-item config:name="IsSelectedFrame" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AnchoredTextOverflowLegacy" config:type="boolean">true</config:config-item>
|
||||
</config:config-item-map-entry>
|
||||
</config:config-item-map-indexed>
|
||||
</config:config-item-set>
|
||||
<config:config-item-set config:name="ooo:configuration-settings">
|
||||
<config:config-item config:name="PrintPaperFromSetup" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintFaxName" config:type="string"/>
|
||||
<config:config-item config:name="PrintSingleJobs" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintProspectRTL" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintProspect" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintTextPlaceholder" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintTables" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrintPageBackground" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrintLeftPages" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrintAnnotationMode" config:type="short">0</config:config-item>
|
||||
<config:config-item config:name="PrintControls" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrintHiddenText" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintDrawings" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="FrameAutowidthWithMorePara" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="HeaderSpacingBelowLastPara" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ProtectFields" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintReversed" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ProtectBookmarks" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UseOldPrinterMetrics" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UseOldNumbering" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AddExternalLeading" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="TreatSingleColumnBreakAsPageBreak" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="IsLabelDocument" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="RsidRoot" config:type="int">517402</config:config-item>
|
||||
<config:config-item config:name="ConsiderTextWrapOnObjPos" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="TableRowKeep" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="TabsRelativeToIndent" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="AddParaLineSpacingToTableCells" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="AllowPrintJobCancel" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="UpdateFromTemplate" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ChartAutoUpdate" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="ContinuousEndnotes" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AddParaTableSpacingAtStart" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AddParaTableSpacing" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AddParaSpacingToTableCells" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="OutlineLevelYieldsNumbering" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AlignTabStopPosition" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmbedOnlyUsedFonts" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="LinkUpdateMode" config:type="short">1</config:config-item>
|
||||
<config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item>
|
||||
<config:config-item config:name="CurrentDatabaseCommand" config:type="string"/>
|
||||
<config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
|
||||
<config:config-item config:name="SmallCapsPercentage66" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ApplyUserData" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="StylesNoDefault" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmbeddedDatabaseName" config:type="string"/>
|
||||
<config:config-item config:name="FloattableNomargins" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="BackgroundParaOverDrawings" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrinterName" config:type="string"/>
|
||||
<config:config-item config:name="UseFormerObjectPositioning" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrinterSetup" config:type="base64Binary"/>
|
||||
<config:config-item config:name="IgnoreFirstLineIndentInNumbering" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="CollapseEmptyCellPara" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="TabOverMargin" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="SaveGlobalDocumentLinks" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="CurrentDatabaseDataSource" config:type="string"/>
|
||||
<config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintEmptyPages" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="ProtectForm" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="AddVerticalFrameOffsets" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="SaveThumbnail" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item>
|
||||
<config:config-item config:name="PrinterPaperFromSetup" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="TabOverflow" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrintGraphics" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PropLineSpacingShrinksFirstLine" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="DoNotResetParaAttrsForNumFont" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="FieldAutoUpdate" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="RedlineProtectionKey" config:type="base64Binary"/>
|
||||
<config:config-item config:name="EmbedComplexScriptFonts" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="DoNotCaptureDrawObjsOnPage" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ClipAsCharacterAnchoredWriterFlyFrames" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintBlackFonts" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="DisableOffPagePositioning" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="SurroundTextWrapSmall" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmbedAsianScriptFonts" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="TabAtLeftIndentForParagraphsInList" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintRightPages" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="Rsid" config:type="int">648908</config:config-item>
|
||||
<config:config-item config:name="MathBaselineAlignment" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="MsWordCompTrailingBlanks" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="MsWordCompMinLineHeightByFly" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmbedFonts" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UnbreakableNumberings" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ClippedPictures" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmbedLatinScriptFonts" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="EmbedSystemFonts" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ApplyParagraphMarkFormatToNumbering" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="SubtractFlysAnchoredAtFlys" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="EmptyDbFieldHidesPara" config:type="boolean">true</config:config-item>
|
||||
</config:config-item-set>
|
||||
</office:settings>
|
||||
</office:document-settings>
|
131
testFiles/settings.xml
Normal file
131
testFiles/settings.xml
Normal file
|
@ -0,0 +1,131 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<office:document-settings xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:xlink="http://www.w3.org/1999/xlink" office:version="1.3">
|
||||
<office:settings>
|
||||
<config:config-item-set config:name="ooo:view-settings">
|
||||
<config:config-item config:name="ViewAreaTop" config:type="long">0</config:config-item>
|
||||
<config:config-item config:name="ViewAreaLeft" config:type="long">0</config:config-item>
|
||||
<config:config-item config:name="ViewAreaWidth" config:type="long">21625</config:config-item>
|
||||
<config:config-item config:name="ViewAreaHeight" config:type="long">9213</config:config-item>
|
||||
<config:config-item config:name="ShowRedlineChanges" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="InBrowseMode" config:type="boolean">false</config:config-item>
|
||||
<config:config-item-map-indexed config:name="Views">
|
||||
<config:config-item-map-entry>
|
||||
<config:config-item config:name="ViewId" config:type="string">view2</config:config-item>
|
||||
<config:config-item config:name="ViewLeft" config:type="long">3401</config:config-item>
|
||||
<config:config-item config:name="ViewTop" config:type="long">2501</config:config-item>
|
||||
<config:config-item config:name="VisibleLeft" config:type="long">0</config:config-item>
|
||||
<config:config-item config:name="VisibleTop" config:type="long">0</config:config-item>
|
||||
<config:config-item config:name="VisibleRight" config:type="long">21624</config:config-item>
|
||||
<config:config-item config:name="VisibleBottom" config:type="long">9211</config:config-item>
|
||||
<config:config-item config:name="ZoomType" config:type="short">0</config:config-item>
|
||||
<config:config-item config:name="ViewLayoutColumns" config:type="short">1</config:config-item>
|
||||
<config:config-item config:name="ViewLayoutBookMode" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ZoomFactor" config:type="short">214</config:config-item>
|
||||
<config:config-item config:name="IsSelectedFrame" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AnchoredTextOverflowLegacy" config:type="boolean">true</config:config-item>
|
||||
</config:config-item-map-entry>
|
||||
</config:config-item-map-indexed>
|
||||
</config:config-item-set>
|
||||
<config:config-item-set config:name="ooo:configuration-settings">
|
||||
<config:config-item config:name="PrintPaperFromSetup" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintFaxName" config:type="string"/>
|
||||
<config:config-item config:name="PrintSingleJobs" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintProspectRTL" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintProspect" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintTextPlaceholder" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintTables" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrintPageBackground" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrintLeftPages" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrintAnnotationMode" config:type="short">0</config:config-item>
|
||||
<config:config-item config:name="PrintControls" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrintHiddenText" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintDrawings" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="FrameAutowidthWithMorePara" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="HeaderSpacingBelowLastPara" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ProtectFields" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintReversed" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ProtectBookmarks" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UseOldPrinterMetrics" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UseOldNumbering" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AddExternalLeading" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="TreatSingleColumnBreakAsPageBreak" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="IsLabelDocument" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="RsidRoot" config:type="int">517402</config:config-item>
|
||||
<config:config-item config:name="ConsiderTextWrapOnObjPos" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="TableRowKeep" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="TabsRelativeToIndent" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="AddParaLineSpacingToTableCells" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AllowPrintJobCancel" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="UpdateFromTemplate" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ChartAutoUpdate" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="ContinuousEndnotes" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AddParaTableSpacingAtStart" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="AddParaTableSpacing" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="AddParaSpacingToTableCells" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="OutlineLevelYieldsNumbering" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AlignTabStopPosition" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmbedOnlyUsedFonts" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="LinkUpdateMode" config:type="short">1</config:config-item>
|
||||
<config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item>
|
||||
<config:config-item config:name="CurrentDatabaseCommand" config:type="string"/>
|
||||
<config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
|
||||
<config:config-item config:name="SmallCapsPercentage66" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ApplyUserData" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="StylesNoDefault" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmbeddedDatabaseName" config:type="string"/>
|
||||
<config:config-item config:name="FloattableNomargins" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="BackgroundParaOverDrawings" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrinterName" config:type="string"/>
|
||||
<config:config-item config:name="UseFormerObjectPositioning" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrinterSetup" config:type="base64Binary"/>
|
||||
<config:config-item config:name="IgnoreFirstLineIndentInNumbering" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="CollapseEmptyCellPara" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="TabOverMargin" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="SaveGlobalDocumentLinks" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="CurrentDatabaseDataSource" config:type="string"/>
|
||||
<config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintEmptyPages" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="ProtectForm" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AddVerticalFrameOffsets" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="SaveThumbnail" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item>
|
||||
<config:config-item config:name="PrinterPaperFromSetup" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="TabOverflow" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PrintGraphics" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="PropLineSpacingShrinksFirstLine" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="DoNotResetParaAttrsForNumFont" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="FieldAutoUpdate" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="RedlineProtectionKey" config:type="base64Binary"/>
|
||||
<config:config-item config:name="EmbedComplexScriptFonts" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="DoNotCaptureDrawObjsOnPage" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ClipAsCharacterAnchoredWriterFlyFrames" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintBlackFonts" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="DisableOffPagePositioning" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="SurroundTextWrapSmall" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmbedAsianScriptFonts" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="TabAtLeftIndentForParagraphsInList" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="PrintRightPages" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="Rsid" config:type="int">639374</config:config-item>
|
||||
<config:config-item config:name="MathBaselineAlignment" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="MsWordCompTrailingBlanks" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="MsWordCompMinLineHeightByFly" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmbedFonts" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="UnbreakableNumberings" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ClippedPictures" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmbedLatinScriptFonts" config:type="boolean">true</config:config-item>
|
||||
<config:config-item config:name="EmbedSystemFonts" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="ApplyParagraphMarkFormatToNumbering" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="SubtractFlysAnchoredAtFlys" config:type="boolean">false</config:config-item>
|
||||
<config:config-item config:name="EmptyDbFieldHidesPara" config:type="boolean">false</config:config-item>
|
||||
</config:config-item-set>
|
||||
</office:settings>
|
||||
</office:document-settings>
|
BIN
testFiles/testFile (copy).odt
Normal file
BIN
testFiles/testFile (copy).odt
Normal file
Binary file not shown.
BIN
testFiles/testFile.odt
Normal file
BIN
testFiles/testFile.odt
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue