summaryrefslogtreecommitdiffstats
path: root/swext/mediawiki/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /swext/mediawiki/src
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'swext/mediawiki/src')
-rw-r--r--swext/mediawiki/src/META-INF/manifest.xml42
-rw-r--r--swext/mediawiki/src/THIRDPARTYLICENSEREADME.html83
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/EditPageParser.java176
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/Helper.java1079
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/MANIFEST.MF1
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/MainThreadDialogExecutor.java158
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/Settings.java310
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java261
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/WikiCancelException.java24
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/WikiDialog.java283
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java416
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/WikiEditorImpl.java353
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/WikiOptionsEventHandlerImpl.java279
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/WikiPropDialog.java372
-rw-r--r--swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java333
-rw-r--r--swext/mediawiki/src/components.rdb19
-rw-r--r--swext/mediawiki/src/description-en-US.txt1
-rw-r--r--swext/mediawiki/src/description.xml34
-rw-r--r--swext/mediawiki/src/filter/mediawiki.ottbin0 -> 6304 bytes
-rw-r--r--swext/mediawiki/src/filter/odt2mediawiki.xsl2012
-rw-r--r--swext/mediawiki/src/registry/data/org/openoffice/Office/Addons.xcu58
-rw-r--r--swext/mediawiki/src/registry/data/org/openoffice/Office/Custom/WikiExtension.xcu132
-rw-r--r--swext/mediawiki/src/registry/data/org/openoffice/Office/OptionsDialog.xcu41
-rw-r--r--swext/mediawiki/src/registry/data/org/openoffice/Office/Paths.xcu27
-rw-r--r--swext/mediawiki/src/registry/data/org/openoffice/Office/ProtocolHandler.xcu27
-rw-r--r--swext/mediawiki/src/registry/data/org/openoffice/TypeDetection/Filter.xcu47
-rw-r--r--swext/mediawiki/src/registry/data/org/openoffice/TypeDetection/Types.xcu35
-rw-r--r--swext/mediawiki/src/registry/schema/org/openoffice/Office/Custom/WikiExtension.xcs188
28 files changed, 6791 insertions, 0 deletions
diff --git a/swext/mediawiki/src/META-INF/manifest.xml b/swext/mediawiki/src/META-INF/manifest.xml
new file mode 100644
index 0000000000..ab4d1054c3
--- /dev/null
+++ b/swext/mediawiki/src/META-INF/manifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+-->
+<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.uno-components"
+ manifest:full-path="components.rdb"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
+ manifest:full-path="Addons.xcu"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
+ manifest:full-path="ProtocolHandler.xcu"/>
+ <manifest:file-entry manifest:full-path="WikiEditor/"
+ manifest:media-type="application/vnd.sun.star.basic-library"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-schema"
+ manifest:full-path="WikiExtension.xcs"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
+ manifest:full-path="WikiExtension.xcu"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
+ manifest:full-path="OptionsDialog.xcu"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
+ manifest:full-path="Filter.xcu"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
+ manifest:full-path="Types.xcu"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
+ manifest:full-path="Paths.xcu"/>
+ <manifest:file-entry manifest:media-type="application/vnd.sun.star.help"
+ manifest:full-path="help"/>
+</manifest:manifest>
diff --git a/swext/mediawiki/src/THIRDPARTYLICENSEREADME.html b/swext/mediawiki/src/THIRDPARTYLICENSEREADME.html
new file mode 100644
index 0000000000..a9efb72a65
--- /dev/null
+++ b/swext/mediawiki/src/THIRDPARTYLICENSEREADME.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta content="text/html; charset=iso-8859-1"
+ http-equiv="Content-Type">
+ <title>THIRDPARTYLICENSEREADME</title>
+</head>
+<body>
+DO NOT TRANSLATE OR LOCALIZE THIS DOCUMENT<br>
+<br>
+<ul id="mozToc">
+<!--mozToc h2 1 h3 2-->
+ <li><a href="#mozTocId3503">The Apache Software
+Foundation
+ </a>
+ <ul>
+ <li><a href="#mozTocId520856">Tomcat
+ </a></li>
+ </ul>
+ </li>
+</ul>
+<br>
+<hr style="width: 100%; height: 2px;">The following software may be
+included in this product: Tomcat 4.0 or higher; Use of any of this
+software is governed by the terms of the license below:<br>
+<h2><a class="mozTocH2" name="mozTocId3503"></a>The Apache Software
+Foundation<br>
+</h2>
+<h3><a class="mozTocH3" name="mozTocId520856"></a>Tomcat<br>
+</h3>
+<br>
+The Apache Software License, Version 1.1
+<br>
+<br>
+Copyright (c) 2001 The Apache Software Foundation. All rights
+reserved.
+<br>
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+<br>
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer. <br>
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution. <br>
+3. The end-user documentation included with the redistribution, if any,
+must include the following acknowledgment: "This product includes
+software developed by the Apache Software Foundation
+(http://www.apache.org/)." Alternately, this acknowledgment may appear
+in the software itself, if and wherever such third-party
+acknowledgments normally appear. <br>
+4. The names "XML-RPC" and "Apache Software Foundation" must not be
+used to endorse or promote products derived from this software without
+prior written permission. For written permission, please contact
+apache@apache.org. <br>
+5. Products derived from this software may not be called "Apache", nor
+may "Apache" appear in their name, without prior written permission of
+the Apache Software Foundation. <br>
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+<br>
+====================================================================
+<br>
+This software consists of voluntary contributions made by many
+individuals on behalf of the Apache Software Foundation. For more
+information on the Apache Software Foundation, please see
+<http:>.
+<br>
+</http:>
+<br>
+</body>
+</html>
diff --git a/swext/mediawiki/src/com/sun/star/wiki/EditPageParser.java b/swext/mediawiki/src/com/sun/star/wiki/EditPageParser.java
new file mode 100644
index 0000000000..114709fae3
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/EditPageParser.java
@@ -0,0 +1,176 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+import javax.swing.text.html.*;
+import javax.swing.text.MutableAttributeSet;
+
+public class EditPageParser extends HTMLEditorKit.ParserCallback
+{
+
+ protected String m_sEditTime = "";
+ protected String m_sEditToken = "";
+ protected String m_sLoginToken = "";
+ protected String m_sMainURL = "";
+
+ private boolean m_bHTMLStartFound = false;
+ private boolean m_bInHead = false;
+
+ protected int m_nWikiArticleStart = -1;
+ protected int m_nWikiArticleEnd = -1;
+ protected int m_nHTMLArticleStart = -1;
+ protected int m_nHTMLArticleEnd = -1;
+ protected int m_nNoArticleInd = -1;
+ protected int m_nErrorInd = -1;
+
+ @Override
+ public void handleComment( char[] data,int pos )
+ {
+ // insert code to handle comments
+ }
+
+ @Override
+ public void handleEndTag( HTML.Tag t,int pos )
+ {
+ if ( t == HTML.Tag.TEXTAREA )
+ {
+ m_nWikiArticleEnd = pos;
+ }
+ else if ( t == HTML.Tag.DIV )
+ {
+ if ( m_bHTMLStartFound )
+ {
+ m_nHTMLArticleStart = pos+6;
+ m_bHTMLStartFound = false;
+ }
+ }
+ else if ( t == HTML.Tag.HEAD )
+ {
+ m_bInHead = false;
+ }
+ }
+
+ @Override
+ public void handleError( String errorMsg,int pos )
+ {
+ }
+
+ @Override
+ public void handleSimpleTag( HTML.Tag t, MutableAttributeSet a,int pos )
+ {
+ // insert code to handle simple tags
+
+ if ( t == HTML.Tag.INPUT )
+ {
+ String sName = ( String ) a.getAttribute( HTML.Attribute.NAME );
+ if ( sName != null )
+ {
+ if ( sName.equalsIgnoreCase( "wpEdittime" ) )
+ {
+ this.m_sEditTime = ( String ) a.getAttribute( HTML.Attribute.VALUE );
+ }
+ else if ( sName.equalsIgnoreCase( "wpEditToken" ) )
+ {
+ this.m_sEditToken = ( String ) a.getAttribute( HTML.Attribute.VALUE );
+ }
+ else if ( sName.equalsIgnoreCase( "wpLoginToken" ) )
+ {
+ this.m_sLoginToken = ( String ) a.getAttribute( HTML.Attribute.VALUE );
+ }
+ }
+
+ }
+ else if ( t == HTML.Tag.LINK )
+ {
+ if ( m_bInHead )
+ {
+ String sName = ( String ) a.getAttribute( HTML.Attribute.HREF );
+ if ( sName != null )
+ {
+ // get the main URL from the first header-link with load.php (which is used for stylesheet)
+ int nPhpFileStart = sName.indexOf( "load.php" );
+ if (nPhpFileStart < 0)
+ // if not found, try header-link with opensearch_desc.php
+ nPhpFileStart = sName.indexOf( "opensearch_desc.php" );
+
+ if ( nPhpFileStart >= 0
+ && m_sMainURL.length() == 0 )
+ {
+ m_sMainURL = sName.substring( 0, nPhpFileStart );
+ }
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public void handleStartTag( HTML.Tag t, MutableAttributeSet a,int pos )
+ {
+ // insert code to handle starting tags
+ String sClass;
+
+ if ( t == HTML.Tag.HEAD )
+ {
+ m_bInHead = true;
+ }
+ else if ( t == HTML.Tag.TEXTAREA )
+ {
+ String sName = ( String ) a.getAttribute( HTML.Attribute.NAME );
+ if ( sName != null && sName.equalsIgnoreCase( "wpTextbox1" ) )
+ {
+ m_nWikiArticleStart = pos;
+ }
+ }
+ else if ( t == HTML.Tag.DIV )
+ {
+ String sId = ( String ) a.getAttribute( HTML.Attribute.ID );
+ sClass = ( String ) a.getAttribute( HTML.Attribute.CLASS );
+ if ( sId != null && sId.equalsIgnoreCase( "contentSub" ) )
+ {
+ m_bHTMLStartFound = true;
+ }
+ if ( sClass != null )
+ {
+ if ( sClass.equalsIgnoreCase( "printfooter" ) )
+ {
+ m_nHTMLArticleEnd = pos;
+ }
+ else if ( sClass.equalsIgnoreCase( "noarticletext" ) )
+ {
+ m_nNoArticleInd = pos;
+ }
+ else if ( sClass.equalsIgnoreCase( "errorbox" ) )
+ {
+ m_nErrorInd = pos;
+ }
+ }
+ }
+ else if ( t == HTML.Tag.P )
+ {
+ sClass = ( String ) a.getAttribute( HTML.Attribute.CLASS );
+ if ( sClass != null && sClass.equalsIgnoreCase( "error" ) )
+ {
+ m_nErrorInd = pos;
+ }
+ }
+ }
+
+
+}
diff --git a/swext/mediawiki/src/com/sun/star/wiki/Helper.java b/swext/mediawiki/src/com/sun/star/wiki/Helper.java
new file mode 100644
index 0000000000..e43091d2e2
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/Helper.java
@@ -0,0 +1,1079 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+import com.sun.star.awt.MessageBoxButtons;
+import com.sun.star.awt.MessageBoxType;
+import com.sun.star.awt.XControl;
+import com.sun.star.awt.XDialog;
+import com.sun.star.awt.XMessageBox;
+import com.sun.star.awt.XMessageBoxFactory;
+import com.sun.star.awt.XWindowPeer;
+import com.sun.star.beans.NamedValue;
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.XContainerQuery;
+import com.sun.star.container.XEnumeration;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.container.XNameContainer;
+import com.sun.star.document.XDocumentPropertiesSupplier;
+import com.sun.star.document.XDocumentProperties;
+import com.sun.star.frame.XModel;
+import com.sun.star.frame.XModuleManager;
+import com.sun.star.io.XInputStream;
+import com.sun.star.io.XOutputStream;
+import com.sun.star.lang.IllegalArgumentException;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XComponent;
+import com.sun.star.system.SystemShellExecuteFlags;
+import com.sun.star.system.XSystemShellExecute;
+import com.sun.star.task.UrlRecord;
+import com.sun.star.task.XInteractionHandler;
+import com.sun.star.task.XMasterPasswordHandling;
+import com.sun.star.task.XPasswordContainer;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.util.XChangesBatch;
+import java.net.*;
+import java.io.*;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.swing.text.html.HTMLEditorKit;
+
+
+public class Helper
+{
+ public static final int GENERALSEND_ERROR = 0;
+ public static final int NOWIKIFILTER_ERROR = 1;
+ public static final int NOURLCONNECTION_ERROR = 2;
+ public static final int WRONGLOGIN_ERROR = 3;
+ public static final int INVALIDURL_ERROR = 4;
+ public static final int NOURL_ERROR = 5;
+
+ public static final int DLG_SENDTITLE = 6;
+ public static final int DLG_WIKIARTICLE = 7;
+
+ public static final int DLG_OK = 9;
+
+ // 11 is reserved
+ public static final int DLG_ADDBUTTON = 12;
+ public static final int DLG_EDITBUTTON = 13;
+ public static final int DLG_SENDBUTTON = 14;
+ public static final int DLG_REMOVEBUTTON = 15;
+
+ public static final int DLG_EDITSETTING_URLLABEL = 16;
+ public static final int DLG_EDITSETTING_USERNAMELABEL = 17;
+ public static final int DLG_EDITSETTING_PASSWORDLABEL = 18;
+
+ public static final int DLG_SENDTOMEDIAWIKI_LABEL1 = 20;
+ public static final int DLG_SENDTOMEDIAWIKI_LABEL2 = 21;
+ public static final int DLG_SENDTOMEDIAWIKI_LABEL3 = 22;
+ public static final int DLG_SENDTOMEDIAWIKI_MINORCHECK = 23;
+ public static final int DLG_SENDTOMEDIAWIKI_BROWSERCHECK = 24;
+ public static final int UNKNOWNCERT_ERROR = 25;
+ public static final int DLG_MEDIAWIKI_TITLE = 26;
+ public static final int DLG_EDITSETTING_ACCOUNTLINE = 27;
+ public static final int DLG_EDITSETTING_WIKILINE = 28;
+ public static final int DLG_EDITSETTING_SAVEBOX = 29;
+ public static final int CANCELSENDING_ERROR = 30;
+ public static final int DLG_MEDIAWIKIEXTENSION_STRING = 31;
+ public static final int DLG_WIKIPAGEEXISTS_LABEL1 = 32;
+
+ private static final int STRINGS_NUM = 33;
+
+ private static final String[] m_pEntryNames = { "GeneralSendError",
+ "NoWikiFilter",
+ "NoConnectionToURL",
+ "WrongLogin",
+ "InvalidURL",
+ "NoURL",
+ "Dlg_SendTitle",
+ "Dlg_WikiArticle",
+ "Dlg_No",
+ "Dlg_OK",
+ "Dlg_Yes",
+ null, // reserved
+ "Dlg_AddButton",
+ "Dlg_EditButton",
+ "Dlg_SendButton",
+ "Dlg_RemoveButton",
+ "Dlg_EditSetting_UrlLabel",
+ "Dlg_EditSetting_UsernameLabel",
+ "Dlg_EditSetting_PasswordLabel",
+ "Dlg_NewWikiPage_Label1",
+ "Dlg_SendToMediaWiki_Label1",
+ "Dlg_SendToMediaWiki_Label2",
+ "Dlg_SendToMediaWiki_Label3",
+ "Dlg_SendToMediaWiki_MinorCheck",
+ "Dlg_SendToMediaWiki_BrowserCheck",
+ "UnknownCert",
+ "Dlg_MediaWiki_Title",
+ "Dlg_EditSetting_AccountLine",
+ "Dlg_EditSetting_WikiLine",
+ "Dlg_EditSetting_SaveBox",
+ "CancelSending",
+ "Dlg_MediaWiki_Extension_String",
+ "Dlg_WikiPageExists_Label1" };
+
+ private static String[] m_pConfigStrings;
+
+ private static boolean m_bAllowConnection = true;
+
+ private static Boolean m_bShowInBrowser = null;
+
+ private static XPasswordContainer m_xPasswordContainer;
+ private static XInteractionHandler m_xInteractionHandler;
+
+ synchronized protected static String GetLocalizedString( XComponentContext xContext, int nID )
+ throws com.sun.star.uno.Exception
+ {
+ if ( nID >= STRINGS_NUM )
+ throw new com.sun.star.uno.RuntimeException();
+
+ if ( m_pConfigStrings == null )
+ {
+ XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/Strings" );
+
+ String[] pStrings = new String[STRINGS_NUM];
+ for ( int nInd = 0; nInd < STRINGS_NUM; nInd++ )
+ if ( m_pEntryNames[nInd] != null )
+ pStrings[nInd] = AnyConverter.toString( xNameAccess.getByName( m_pEntryNames[nInd] ) );
+ else
+ pStrings[nInd] = "";
+
+ m_pConfigStrings = pStrings;
+ }
+
+ return m_pConfigStrings[nID];
+ }
+
+ synchronized protected static void AllowConnection( boolean bAllow )
+ {
+ m_bAllowConnection = bAllow;
+ // TODO: how to shut down any pending connections?
+ // hope it doesn't matter?
+ }
+
+ synchronized protected static boolean IsConnectionAllowed()
+ {
+ return m_bAllowConnection;
+ }
+
+ synchronized protected static boolean GetShowInBrowserByDefault( XComponentContext xContext )
+ {
+ if ( m_bShowInBrowser == null )
+ {
+ try
+ {
+ XNameAccess xAccess = Helper.GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/Settings" );
+ m_bShowInBrowser = Boolean.valueOf( AnyConverter.toBoolean( xAccess.getByName( "PreselectShowBrowser" ) ) );
+ }
+ catch( com.sun.star.uno.Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ return m_bShowInBrowser != null ? m_bShowInBrowser.booleanValue() : false;
+ }
+
+ synchronized protected static void SetShowInBrowserByDefault( XComponentContext xContext, boolean bValue )
+ {
+ try
+ {
+ m_bShowInBrowser = Boolean.valueOf( bValue );
+
+ XPropertySet xProps = Helper.GetConfigProps( xContext, "org.openoffice.Office.Custom.WikiExtension/Settings" );
+ xProps.setPropertyValue( "PreselectShowBrowser", Boolean.valueOf( bValue ) );
+ XChangesBatch xBatch = UnoRuntime.queryInterface( XChangesBatch.class, xProps );
+ if ( xBatch != null )
+ xBatch.commitChanges();
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ synchronized protected static XPasswordContainer GetPasswordContainer( XComponentContext xContext )
+ throws com.sun.star.uno.Exception
+ {
+ if ( m_xPasswordContainer == null && xContext != null )
+ {
+ XMultiComponentFactory xFactory = xContext.getServiceManager();
+ if ( xFactory != null )
+ m_xPasswordContainer = UnoRuntime.queryInterface(
+ XPasswordContainer.class,
+ xFactory.createInstanceWithContext( "com.sun.star.task.PasswordContainer", xContext ) );
+ }
+
+ if ( m_xPasswordContainer == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ return m_xPasswordContainer;
+ }
+
+ synchronized protected static XInteractionHandler GetInteractionHandler( XComponentContext xContext )
+ throws com.sun.star.uno.Exception
+ {
+ if ( m_xInteractionHandler == null && xContext != null )
+ {
+ XMultiComponentFactory xFactory = xContext.getServiceManager();
+ if ( xFactory != null )
+ m_xInteractionHandler = UnoRuntime.queryInterface(
+ XInteractionHandler.class,
+ xFactory.createInstanceWithContext( "com.sun.star.task.InteractionHandler", xContext ) );
+ }
+
+ if ( m_xInteractionHandler == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ return m_xInteractionHandler;
+ }
+
+ protected static String GetMainURL( String sWebPage, String sVURL )
+ {
+ String sResultURL = "";
+ try
+ {
+ StringReader aReader = new StringReader( sWebPage );
+ HTMLEditorKit.Parser aParser = GetHTMLParser();
+ EditPageParser aCallback = new EditPageParser();
+
+ aParser.parse( aReader, aCallback, true );
+ sResultURL = aCallback.m_sMainURL;
+
+ if ( !sResultURL.startsWith( "http" ) )
+ {
+ //if the url is only relative then complete it
+ URL aURL = new URL( sVURL );
+ sResultURL = aURL.getProtocol() + "://" + aURL.getHost() + sResultURL;
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ if ( sResultURL.length() == 0 )
+ {
+ // usually that should not happen
+ // workaround: try to get index.php from the provided URL
+ int nIndex = sVURL.indexOf( "index.php" );
+ if ( nIndex >= 0 )
+ sResultURL = sVURL.substring( 0, nIndex );
+ }
+
+ return sResultURL;
+ }
+
+ protected static String GetRedirectURL( String sWebPage, String sURL )
+ {
+ //scrape the HTML source and find the EditURL
+ // TODO/LATER: Use parser in future
+
+ int nInd = sWebPage.indexOf( "http-equiv=\"refresh\"" );
+ if ( nInd == -1 )
+ return "";
+
+ String sResultURL = "";
+ int nContent = sWebPage.indexOf( "content=", nInd );
+ if ( nContent > 0 )
+ {
+ int nURL = sWebPage.indexOf( "URL=", nContent );
+ if ( nURL > 0 )
+ {
+ int nEndURL = sWebPage.indexOf('"', nURL );
+ if ( nEndURL > 0 )
+ sResultURL = sWebPage.substring( nURL + 4, nEndURL );
+ }
+ }
+
+ try
+ {
+ URL aURL = new URL( sURL );
+ if ( !sResultURL.startsWith( aURL.getProtocol() ))
+ {
+ //if the url is only relative then complete it
+ if ( sResultURL.startsWith( "/" ) )
+ sResultURL = aURL.getProtocol() + "://" + aURL.getHost() + sResultURL;
+ else
+ sResultURL = aURL.getProtocol() + "://" + aURL.getHost() + aURL.getPath() + sResultURL;
+ }
+ }
+ catch ( MalformedURLException ex )
+ {
+ ex.printStackTrace();
+ }
+
+ return sResultURL;
+
+ }
+
+ protected static String CreateTempFile( XComponentContext xContext )
+ {
+ String sURL = "";
+ try
+ {
+ Object oTempFile = xContext.getServiceManager().createInstanceWithContext( "com.sun.star.io.TempFile", xContext );
+ XPropertySet xPropertySet = UnoRuntime.queryInterface( XPropertySet.class, oTempFile );
+ xPropertySet.setPropertyValue( "RemoveFile", Boolean.FALSE );
+ sURL = ( String ) xPropertySet.getPropertyValue( "Uri" );
+
+ XInputStream xInputStream = UnoRuntime.queryInterface( XInputStream.class, oTempFile );
+ xInputStream.closeInput();
+ XOutputStream xOutputStream = UnoRuntime.queryInterface( XOutputStream.class, oTempFile );
+ xOutputStream.closeOutput();
+ } catch ( com.sun.star.uno.Exception ex )
+ {
+ ex.printStackTrace();
+ }
+ return sURL;
+ }
+
+ private static void close(BufferedReader c) {
+ if (c == null) return;
+ try {
+ c.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected static String EachLine( String sURL )
+ {
+ String sText = "";
+ BufferedReader aBufReader = null;
+ try
+ {
+ URL aURL = new URL( sURL );
+ File aFile = new File( aURL.getFile() );
+ InputStreamReader aInputReader = new InputStreamReader( new FileInputStream( aFile ), "UTF-8" );
+ aBufReader = new BufferedReader( aInputReader );
+
+ StringBuffer aBuf = new StringBuffer();
+ String sEachLine = aBufReader.readLine();
+
+ while( sEachLine != null )
+ {
+ aBuf.append( sEachLine );
+ aBuf.append( "\n" );
+
+ sEachLine = aBufReader.readLine();
+ }
+ sText = aBuf.toString();
+
+ aBufReader.close();
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ }
+ finally {
+ close(aBufReader);
+ }
+ return sText;
+ }
+
+ protected static String GetDocTitle( XModel xDoc )
+ {
+ XDocumentPropertiesSupplier xDocPropSup =
+ UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xDoc);
+ XDocumentProperties xDocProps = xDocPropSup.getDocumentProperties();
+ return xDocProps.getTitle();
+ }
+
+ protected static void SetDocTitle( XModel xDoc, String sTitle )
+ {
+ XDocumentPropertiesSupplier xDocPropSup =
+ UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xDoc);
+ XDocumentProperties xDocProps = xDocPropSup.getDocumentProperties();
+ xDocProps.setTitle(sTitle);
+ }
+
+ protected static String GetDocServiceName( XComponentContext xContext, XModel xModel )
+ {
+ String aDocServiceName = "";
+ if ( xModel != null && xContext != null )
+ {
+ try
+ {
+ XMultiComponentFactory xFactory = xContext.getServiceManager();
+ if ( xFactory == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ Object oModuleManager = xFactory.createInstanceWithContext( "com.sun.star.frame.ModuleManager", xContext );
+ XModuleManager xModuleManager = UnoRuntime.queryInterface( XModuleManager.class, oModuleManager );
+ if ( xModuleManager != null )
+ aDocServiceName = xModuleManager.identify( xModel );
+ }
+ catch( java.lang.Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ return aDocServiceName;
+ }
+
+ protected static String GetFilterName( XComponentContext xContext, String aTypeName, String aDocServiceName )
+ {
+ if ( xContext == null || aTypeName == null || aTypeName.length() == 0
+ || aDocServiceName == null || aDocServiceName.length() == 0 ) {
+ return "";
+ }
+ String aFilterName = "";
+ try
+ {
+ Object oFilterFactory = xContext.getServiceManager().createInstanceWithContext( "com.sun.star.document.FilterFactory", xContext );
+ XContainerQuery xQuery = UnoRuntime.queryInterface( XContainerQuery.class, oFilterFactory );
+ if ( xQuery != null )
+ {
+ NamedValue[] aRequest = new NamedValue[2];
+ aRequest[0] = new NamedValue( "Type", aTypeName );
+ aRequest[1] = new NamedValue( "DocumentService", aDocServiceName );
+
+ XEnumeration xSet = xQuery.createSubSetEnumerationByProperties( aRequest );
+ if ( xSet != null )
+ {
+ boolean bAcceptable = false;
+ while ( xSet.hasMoreElements() && !bAcceptable )
+ {
+ PropertyValue[] pFilterProps = ( PropertyValue[] )AnyConverter.toArray( xSet.nextElement() );
+ if ( pFilterProps != null )
+ {
+ int nLen = pFilterProps.length;
+ String aTmpFilter = null;
+
+ for ( int nInd = 0; nInd < nLen; nInd++ )
+ {
+ if ( pFilterProps[nInd].Name.equals( "Name" ) )
+ aTmpFilter = AnyConverter.toString( pFilterProps[nInd].Value );
+ else if ( pFilterProps[nInd].Name.equals( "Flags" ) )
+ bAcceptable = ( ( AnyConverter.toInt( pFilterProps[nInd].Value ) & 2 ) == 2 ); // must allow export
+ }
+
+ if ( bAcceptable )
+ aFilterName = aTmpFilter;
+ }
+ }
+ }
+ }
+ }
+ catch( java.lang.Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ return aFilterName;
+ }
+
+ private static XMultiServiceFactory GetConfigurationProvider( XComponentContext xContext )
+ throws com.sun.star.uno.Exception
+ {
+ XMultiServiceFactory xConfigurationProvider = null;
+ if ( xContext != null )
+ {
+ XMultiComponentFactory xFactory = xContext.getServiceManager();
+ Object oConfigProvider = xFactory.createInstanceWithContext( "com.sun.star.configuration.ConfigurationProvider", xContext );
+ xConfigurationProvider = UnoRuntime.queryInterface( XMultiServiceFactory.class, oConfigProvider );
+ }
+
+ if ( xConfigurationProvider == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ return xConfigurationProvider;
+ }
+
+ private static Object GetConfig( XComponentContext xContext, String sNodepath, boolean bWriteAccess )
+ throws com.sun.star.uno.Exception
+ {
+ if ( xContext == null || sNodepath == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ PropertyValue aVal = new PropertyValue();
+ aVal.Name = "nodepath";
+ aVal.Value = sNodepath;
+ Object[] aArgs = new Object[1];
+ aArgs[0] = aVal;
+
+ return GetConfigurationProvider( xContext ).createInstanceWithArguments(
+ ( bWriteAccess ? "com.sun.star.configuration.ConfigurationUpdateAccess"
+ : "com.sun.star.configuration.ConfigurationAccess" ),
+ aArgs );
+ }
+
+ private static XPropertySet GetConfigProps( XComponentContext xContext, String sNodepath )
+ throws com.sun.star.uno.Exception
+ {
+ XPropertySet xProps = UnoRuntime.queryInterface( XPropertySet.class, GetConfig( xContext, sNodepath, true ) );
+ if ( xProps == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ return xProps;
+ }
+
+
+ protected static XNameContainer GetConfigNameContainer( XComponentContext xContext, String sNodepath )
+ throws com.sun.star.uno.Exception
+ {
+ XNameContainer xContainer = UnoRuntime.queryInterface( XNameContainer.class, GetConfig( xContext, sNodepath, true ) );
+ if ( xContainer == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ return xContainer;
+ }
+
+ protected static XNameAccess GetConfigNameAccess( XComponentContext xContext, String sNodepath )
+ throws com.sun.star.uno.Exception
+ {
+ XNameAccess xNameAccess = UnoRuntime.queryInterface( XNameAccess.class, GetConfig( xContext, sNodepath, false ) );
+ if ( xNameAccess == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ return xNameAccess;
+ }
+
+ private static Proxy GetConfigurationProxy(URI uri, XComponentContext xContext)
+ {
+ assert(uri != null);
+ assert(xContext != null);
+
+ try
+ {
+ XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Inet/Settings" );
+
+ int nProxyType = AnyConverter.toInt( xNameAccess.getByName( "ooInetProxyType" ) );
+ if ( nProxyType == 0 ) {
+ return Proxy.NO_PROXY;
+ } else {
+ if ( nProxyType == 1 )
+ {
+ // system proxy
+ return null;
+ }
+ else if ( nProxyType == 2 )
+ {
+ String aProxyNameProp = "ooInetHTTPProxyName";
+ String aProxyPortProp = "ooInetHTTPProxyPort";
+
+ if (uri.getScheme().equals("https"))
+ {
+ aProxyNameProp = "ooInetHTTPSProxyName";
+ aProxyPortProp = "ooInetHTTPSProxyPort";
+ }
+
+ String aProxyName = AnyConverter.toString( xNameAccess.getByName( aProxyNameProp ) );
+
+ int nProxyPort = 80;
+
+ Object aPortNo = xNameAccess.getByName( aProxyPortProp );
+ if ( !AnyConverter.isVoid( aPortNo ) )
+ nProxyPort = AnyConverter.toInt( aPortNo );
+
+ if ( nProxyPort == -1 )
+ nProxyPort = 80;
+
+ // TODO: check whether the URL is in the NoProxy list
+ InetSocketAddress address = new InetSocketAddress(aProxyName, nProxyPort);
+ return new Proxy(Proxy.Type.HTTP, address);
+ }
+ }
+ }
+ catch( java.lang.Exception e )
+ {
+ e.printStackTrace();
+ }
+ return null; // invalid configuration value?
+ }
+
+ protected static void ShowURLInBrowser( XComponentContext xContext, String sURL )
+ {
+ if ( xContext != null && sURL != null && sURL.length() > 0 )
+ {
+ try
+ {
+ Object oSystemShell = xContext.getServiceManager().createInstanceWithContext( "com.sun.star.system.SystemShellExecute", xContext );
+ XSystemShellExecute xSystemShell = UnoRuntime.queryInterface( XSystemShellExecute.class, oSystemShell );
+ if ( xSystemShell != null )
+ xSystemShell.execute( sURL, "", SystemShellExecuteFlags.URIS_ONLY );
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected static HttpURLConnection PrepareMethod(String method, URI uri, XComponentContext xContext)
+ throws WikiCancelException, IOException, SSLException
+ {
+ assert(method != null);
+ assert(uri != null);
+ assert(xContext != null);
+
+ if (!IsConnectionAllowed()) {
+ throw new WikiCancelException();
+ }
+
+ if (java.net.CookieHandler.getDefault() == null) {
+ // set a cookie manager so cookies don't get lost
+ // apparently it's not possible to do that on a per-connection
+ // basis but only globally?
+ java.net.CookieHandler.setDefault(new java.net.CookieManager());
+ }
+
+ Proxy proxy = GetConfigurationProxy(uri, xContext);
+ HttpURLConnection conn = null;
+ if (proxy != null) {
+ conn = (HttpURLConnection) uri.toURL().openConnection(proxy);
+ } else {
+ conn = (HttpURLConnection) uri.toURL().openConnection();
+ }
+
+ boolean isAllowedInsecure;
+ try {
+ XNameAccess xNameAccess = GetConfigNameAccess(xContext, "org.openoffice.Office.Security/Net");
+ isAllowedInsecure = AnyConverter.toBoolean(xNameAccess.getByName("AllowInsecureProtocols"));
+ } catch (Exception e) {
+ throw new RuntimeException("failed to read configuration", e);
+ }
+ if (!isAllowedInsecure) {
+ if (!uri.getScheme().equals("https")) {
+ throw new IllegalArgumentException("insecure connection not allowed by configuration", null, (short)0);
+ }
+ try {
+ SSLContext context = SSLContext.getInstance("TLSv1.2");
+ context.init(null, null, null); // defaults
+ ((HttpsURLConnection) conn).setSSLSocketFactory(context.getSocketFactory());
+ } catch (Exception e) {
+ throw new RuntimeException("failed to create SSLContext", e);
+ }
+ }
+ else if (uri.getScheme().equals("https") && AllowUnknownCert(xContext, uri.getHost()))
+ {
+ // let unknown certificates be accepted
+ ((HttpsURLConnection) conn).setSSLSocketFactory(new WikiProtocolSocketFactory());
+ }
+
+// enable this to help debug connections where TLS gets in the way
+// ((HttpsURLConnection) conn).setSSLSocketFactory(new LoggingProtocolSocketFactory());
+
+ conn.setRequestMethod(method);
+ // TODO: is it possible to read the version from the extension metadata?
+ conn.setRequestProperty("User-Agent", "LibreOffice Wiki Publisher 1.2.0");
+ // note: don't connect yet so that the caller can do some further setup
+
+ return conn;
+ }
+
+ protected static String ReadResponseBody(HttpURLConnection conn)
+ throws IOException
+ {
+ String ret = null;
+ InputStream stream = conn.getInputStream();
+ try {
+ // there doesn't seem to be an easier way get the content encoding
+ String type = conn.getContentType();
+ String charset = "ISO-8859-1"; // default in RFC2616
+ for (String param : type.split(";")) {
+ if (param.trim().toLowerCase().startsWith("charset=")) {
+ charset = param.trim().substring("charset=".length());
+ break;
+ }
+ }
+ BufferedReader br =
+ new BufferedReader(new InputStreamReader(stream, charset));
+ StringBuilder buf = new StringBuilder();
+ String line;
+ while ((line = br.readLine()) != null) {
+ buf.append(line);
+ }
+ ret = buf.toString();
+ } finally {
+ stream.close();
+ }
+ return ret;
+ }
+
+ private static class HTMLParse extends HTMLEditorKit
+ {
+
+ @Override
+ public HTMLEditorKit.Parser getParser()
+ {
+ return super.getParser();
+ }
+ }
+
+ protected static HTMLEditorKit.Parser GetHTMLParser()
+ {
+ return new HTMLParse().getParser();
+ }
+
+ private static boolean LoginReportsError( String sRespond )
+ {
+ boolean bResult = true;
+ if ( sRespond != null )
+ {
+ try
+ {
+ StringReader aReader = new StringReader( sRespond );
+ HTMLEditorKit.Parser aParser = GetHTMLParser();
+ EditPageParser aCallback = new EditPageParser();
+
+ aParser.parse( aReader, aCallback, true );
+ bResult = ( aCallback.m_nErrorInd >= 0 );
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ return bResult;
+ }
+
+ private static String GetLoginToken( String sLoginPage )
+ {
+ String sResult = "";
+ if ( sLoginPage != null && sLoginPage.length() > 0 )
+ {
+ try
+ {
+ StringReader aReader = new StringReader( sLoginPage );
+ HTMLEditorKit.Parser aParser = Helper.GetHTMLParser();
+ EditPageParser aCallbacks = new EditPageParser();
+
+ aParser.parse( aReader, aCallbacks, true );
+ sResult = aCallbacks.m_sLoginToken;
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ return sResult;
+ }
+
+ protected static boolean Login(URI aMainURL, String sWikiUser, String sWikiPass, XComponentContext xContext)
+ throws java.io.IOException, WikiCancelException, URISyntaxException
+ {
+ boolean success = false;
+
+ if ( sWikiUser != null && sWikiPass != null && xContext != null )
+ {
+ String sLoginPage = null;
+ URI aURI = new URI(aMainURL.toString() + "index.php?title=Special:Userlogin");
+ HttpURLConnection connGet = PrepareMethod("GET", aURI, xContext);
+ connGet.setInstanceFollowRedirects(true);
+
+ connGet.connect();
+ int nResultCode = connGet.getResponseCode();
+ if (nResultCode == 200) {
+ sLoginPage = ReadResponseBody(connGet);
+ }
+
+ if ( sLoginPage != null )
+ {
+ String sLoginToken = GetLoginToken( sLoginPage );
+
+ URI aPostURI = new URI(aMainURL.toString() + "index.php?title=Special:Userlogin&action=submitlogin");
+
+ HttpURLConnection connPost = PrepareMethod("POST", aPostURI, xContext);
+ connPost.setInstanceFollowRedirects(true);
+ connPost.setDoInput(true);
+ connPost.setDoOutput(true);
+ connPost.connect();
+
+ OutputStreamWriter post = new OutputStreamWriter(connPost.getOutputStream(), "UTF-8");
+ try
+ {
+ post.write("wpName=");
+ post.write(URLEncoder.encode(sWikiUser, "UTF-8"));
+ post.write("&wpRemember=1");
+ post.write("&wpPassword=");
+ post.write(URLEncoder.encode(sWikiPass, "UTF-8"));
+
+ if (sLoginToken.length() > 0) {
+ post.write("&wpLoginToken=");
+ post.write(URLEncoder.encode(sLoginToken, "UTF-8"));
+ }
+
+ String[][] pArgs = GetSpecialArgs( xContext, aMainURL.getHost() );
+ if ( pArgs != null )
+ for ( int nArgInd = 0; nArgInd < pArgs.length; nArgInd++ )
+ if ( pArgs[nArgInd].length == 2 && pArgs[nArgInd][0] != null && pArgs[nArgInd][1] != null )
+ {
+ post.write("&");
+ post.write(URLEncoder.encode(pArgs[nArgInd][0], "UTF-8"));
+ post.write("=");
+ post.write(URLEncoder.encode(pArgs[nArgInd][0], "UTF-8"));
+ }
+
+ post.flush();
+ }
+ finally
+ {
+ post.close();
+ }
+
+ nResultCode = connPost.getResponseCode();
+
+ if ( nResultCode == 200 )
+ {
+ String sResult = ReadResponseBody(connPost);
+ if ( !LoginReportsError( sResult ) )
+ success = true;
+ }
+ }
+ }
+
+ return success;
+ }
+
+ protected static String[] GetPasswordsForURLAndUser( XComponentContext xContext, String sURL, String sUserName )
+ {
+ String[] aResult = null;
+
+ try
+ {
+ if ( xContext != null && sURL != null && sURL.length() > 0 && sUserName != null && sUserName.length() > 0 )
+ {
+ UrlRecord aRec = GetPasswordContainer( xContext ).findForName( sURL, sUserName, GetInteractionHandler( xContext ) );
+ if ( aRec != null && aRec.UserList != null && aRec.UserList.length > 0
+ && aRec.UserList[0].UserName.equals( sUserName ) )
+ aResult = aRec.UserList[0].Passwords;
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ return aResult;
+ }
+
+ protected static boolean PasswordStoringIsAllowed( XComponentContext xContext )
+ {
+ boolean bResult = false;
+ try
+ {
+ XMasterPasswordHandling xMasterHdl = UnoRuntime.queryInterface( XMasterPasswordHandling.class, GetPasswordContainer( xContext ) );
+ if ( xMasterHdl != null )
+ bResult = xMasterHdl.isPersistentStoringAllowed();
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ return bResult;
+ }
+
+ protected static void ShowError( XComponentContext xContext, XDialog xDialog, int nTitleID, int nErrorID, String sArg, boolean bQuery )
+ {
+ XWindowPeer xPeer = null;
+ XControl xControl = UnoRuntime.queryInterface( XControl.class, xDialog );
+ if ( xControl != null )
+ xPeer = xControl.getPeer();
+ ShowError( xContext, xPeer, nTitleID, nErrorID, sArg, bQuery );
+ }
+
+ protected static boolean ShowError( XComponentContext xContext, XWindowPeer xParentPeer, int nTitleID, int nErrorID, String sArg, boolean bQuery )
+ {
+ boolean bResult = false;
+
+ if ( xContext != null && nErrorID >= 0 && nErrorID < STRINGS_NUM )
+ {
+ String sError = null;
+ String sTitle = "";
+
+ try
+ {
+ sError = GetLocalizedString( xContext, nErrorID );
+ if ( sError != null && sArg != null )
+ sError = sError.replaceAll( "\\$ARG1", sArg );
+
+ sTitle = GetLocalizedString( xContext, nTitleID );
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ if ( sError == null )
+ sError = "Error: " + nErrorID;
+
+ if ( xParentPeer != null )
+ {
+ XMessageBoxFactory xMBFactory = null;
+ XMessageBox xMB = null;
+ try
+ {
+ XMultiComponentFactory xFactory = xContext.getServiceManager();
+ if ( xFactory != null )
+ xMBFactory = UnoRuntime.queryInterface(
+ XMessageBoxFactory.class,
+ xFactory.createInstanceWithContext( "com.sun.star.awt.Toolkit", xContext ) );
+
+ if ( xMBFactory != null )
+ {
+ if ( bQuery )
+ {
+ xMB = xMBFactory.createMessageBox(
+ xParentPeer,
+ MessageBoxType.QUERYBOX,
+ MessageBoxButtons.BUTTONS_YES_NO | MessageBoxButtons.DEFAULT_BUTTON_NO,
+ sTitle,
+ sError );
+ }
+ else
+ {
+ xMB = xMBFactory.createMessageBox(
+ xParentPeer,
+ MessageBoxType.ERRORBOX,
+ MessageBoxButtons.BUTTONS_OK,
+ sTitle,
+ sError );
+ }
+ if ( xMB != null )
+ {
+ bResult = MainThreadDialogExecutor.Execute( xContext, xMB );
+ }
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ if ( xMB != null )
+ Dispose( xMB );
+ }
+ }
+ }
+
+ return bResult;
+ }
+
+ private static boolean AllowUnknownCert( XComponentContext xContext, String aURL )
+ {
+ try
+ {
+ XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/SpecialData" );
+ if ( xNameAccess.hasByName( aURL ) )
+ {
+ XNameAccess xEntry = UnoRuntime.queryInterface( XNameAccess.class, xNameAccess.getByName( aURL ) );
+ if ( xEntry != null && xEntry.hasByName( "AllowUnknownCertificate" ) )
+ return AnyConverter.toBoolean( xEntry.getByName( "AllowUnknownCertificate" ) );
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+ private static String[][] GetSpecialArgs( XComponentContext xContext, String aURL )
+ {
+ try
+ {
+ XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Office.Custom.WikiExtension/SpecialData" );
+ if ( xNameAccess.hasByName( aURL ) )
+ {
+ XNameAccess xEntry = UnoRuntime.queryInterface( XNameAccess.class, xNameAccess.getByName( aURL ) );
+ if ( xEntry != null )
+ {
+ XNameAccess xArgs = UnoRuntime.queryInterface( XNameAccess.class, xEntry.getByName( "AdditionalLoginArguments" ) );
+ if ( xArgs != null )
+ {
+ String[] pNames = xArgs.getElementNames();
+ if ( pNames != null && pNames.length > 0 )
+ {
+ String[][] pResult = new String[pNames.length][2];
+ for ( int nInd = 0; nInd < pNames.length; nInd++ )
+ {
+ XNameAccess xArgument = UnoRuntime.queryInterface( XNameAccess.class, xArgs.getByName( pNames[nInd] ) );
+ if ( xArgument == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ pResult[nInd][0] = pNames[nInd];
+ pResult[nInd][1] = AnyConverter.toString( xArgument.getByName( "Value" ) );
+ }
+
+ return pResult;
+ }
+ }
+ }
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ protected static boolean AllowThreadUsage( XComponentContext xContext )
+ {
+ if ( xContext != null )
+ {
+ try
+ {
+ XMultiComponentFactory xFactory = xContext.getServiceManager();
+ if ( xFactory == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ Object oCheckCallback = xFactory.createInstanceWithContext( "com.sun.star.awt.AsyncCallback", xContext );
+ return ( oCheckCallback != null );
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ return false;
+ }
+
+ public static void Dispose( Object oObject )
+ {
+ if ( oObject != null )
+ {
+ try
+ {
+ XComponent xComp = UnoRuntime.queryInterface( XComponent.class, oObject );
+ if ( xComp != null )
+ xComp.dispose();
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+}
+
diff --git a/swext/mediawiki/src/com/sun/star/wiki/MANIFEST.MF b/swext/mediawiki/src/com/sun/star/wiki/MANIFEST.MF
new file mode 100644
index 0000000000..6f900e21f5
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/MANIFEST.MF
@@ -0,0 +1 @@
+RegistrationClassName: com.sun.star.wiki.WikiEditorImpl
diff --git a/swext/mediawiki/src/com/sun/star/wiki/MainThreadDialogExecutor.java b/swext/mediawiki/src/com/sun/star/wiki/MainThreadDialogExecutor.java
new file mode 100644
index 0000000000..a6ee07fc85
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/MainThreadDialogExecutor.java
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+import com.sun.star.uno.Any;
+import com.sun.star.awt.XDialog;
+import com.sun.star.awt.XCallback;
+import com.sun.star.awt.XMessageBox;
+import com.sun.star.awt.XRequestCallback;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+
+public class MainThreadDialogExecutor implements XCallback
+{
+ private WikiDialog m_aWikiDialog;
+ private XDialog m_xDialog;
+ private XMessageBox m_xMessageBox;
+ private boolean m_bResult = false;
+ private boolean m_bCalled = false;
+ private boolean m_bClose = false;
+
+ public static boolean Show( XComponentContext xContext, WikiDialog aWikiDialog )
+ {
+ MainThreadDialogExecutor aExecutor = new MainThreadDialogExecutor( aWikiDialog );
+ return GetCallback( xContext, aExecutor );
+ }
+
+
+
+ public static boolean Execute( XComponentContext xContext, XMessageBox xMessageBox )
+ {
+ MainThreadDialogExecutor aExecutor = new MainThreadDialogExecutor( xMessageBox );
+ return GetCallback( xContext, aExecutor );
+ }
+
+ public static boolean Close( XComponentContext xContext, XDialog xDialog )
+ {
+ MainThreadDialogExecutor aExecutor = new MainThreadDialogExecutor( xDialog );
+ aExecutor.m_bClose = true;
+ aExecutor.m_bCalled = true; // no yielding, asynchronous closing
+ return GetCallback( xContext, aExecutor );
+ }
+
+ private static boolean GetCallback( XComponentContext xContext, MainThreadDialogExecutor aExecutor )
+ {
+ if (aExecutor == null)
+ return false;
+
+ try
+ {
+ String aThreadName = null;
+ Thread aCurThread = Thread.currentThread();
+ if ( aCurThread != null )
+ aThreadName = aCurThread.getName();
+
+ if ( aThreadName != null && aThreadName.equals( "com.sun.star.thread.WikiEditorSendingThread" ) )
+ {
+ // the main thread should be accessed asynchronously
+ XMultiComponentFactory xFactory = xContext.getServiceManager();
+ if ( xFactory == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ XRequestCallback xRequest = UnoRuntime.queryInterface(
+ XRequestCallback.class,
+ xFactory.createInstanceWithContext( "com.sun.star.awt.AsyncCallback", xContext ) );
+ if ( xRequest != null )
+ {
+ xRequest.addCallback( aExecutor, Any.VOID );
+ do
+ {
+ Thread.yield();
+ }
+ while( !aExecutor.m_bCalled );
+ }
+ }
+ else
+ {
+ // handle it as a main thread
+ aExecutor.notify( Any.VOID );
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ return aExecutor.GetResult();
+ }
+
+ private MainThreadDialogExecutor( WikiDialog aWikiDialog )
+ {
+ m_aWikiDialog = aWikiDialog;
+ }
+
+ private MainThreadDialogExecutor( XDialog xDialog )
+ {
+ m_xDialog = xDialog;
+ }
+
+ private MainThreadDialogExecutor( XMessageBox xMessageBox )
+ {
+ m_xMessageBox = xMessageBox;
+ }
+
+ private boolean GetResult()
+ {
+ return m_bResult;
+ }
+
+ public void notify( Object aData )
+ {
+ if ( m_aWikiDialog != null )
+ m_bResult = m_aWikiDialog.show();
+ else if ( m_xDialog != null )
+ {
+ if ( !m_bClose )
+ m_bResult = ( m_xDialog.execute() == 1 );
+ else
+ {
+ try
+ {
+ m_xDialog.endExecute();
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ m_bResult = true;
+ }
+ }
+ else if ( m_xMessageBox != null )
+ {
+ int nRes = m_xMessageBox.execute();
+ m_bResult = ( nRes == com.sun.star.awt.MessageBoxResults.OK
+ || nRes == com.sun.star.awt.MessageBoxResults.YES );
+ }
+
+ m_bCalled = true;
+ }
+}
+
diff --git a/swext/mediawiki/src/com/sun/star/wiki/Settings.java b/swext/mediawiki/src/com/sun/star/wiki/Settings.java
new file mode 100644
index 0000000000..34e11e13e8
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/Settings.java
@@ -0,0 +1,310 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.container.XNameContainer;
+import com.sun.star.container.XNameReplace;
+import com.sun.star.lang.XSingleServiceFactory;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.util.XChangesBatch;
+
+public class Settings
+{
+
+ /* Singleton */
+ private static Settings m_instance;
+
+
+ private final XComponentContext m_xContext;
+ private final List<Map<String, String>> m_WikiConnections = new ArrayList<Map<String, String>>();
+ private final List<Map<String, Object>> m_aWikiDocs = new ArrayList<Map<String, Object>>();
+
+ private Settings( XComponentContext ctx )
+ {
+ m_xContext=ctx;
+ loadConfiguration();
+ }
+
+
+ public static synchronized Settings getSettings( XComponentContext ctx )
+ {
+ if ( m_instance == null )
+ m_instance = new Settings( ctx );
+ return m_instance;
+ }
+
+
+ public void addWikiCon ( Map<String, String> wikiCon )
+ {
+ m_WikiConnections.add( wikiCon );
+ }
+
+
+ private String getWikiConUrlByNumber( int num )
+ {
+ String url = "";
+ if ( num >=0 && num < m_WikiConnections.size() )
+ {
+ Map<String,String> ht = m_WikiConnections.get( num );
+ url = ht.get( "Url" );
+ }
+ return url;
+ }
+
+
+ public void addWikiDoc ( Map<String, Object> aWikiDoc )
+ {
+ String sURL = ( String ) aWikiDoc.get( "CompleteUrl" );
+ Map<String,Object> aEntry = getDocByCompleteUrl( sURL );
+
+ if ( aEntry != null )
+ {
+ // add doc to the end, even if it has been added before
+ m_aWikiDocs.remove( aEntry );
+ }
+ else if ( m_aWikiDocs.size() > 10 )
+ {
+ // if the number of elements has reached maximum the oldest element should be removed
+ m_aWikiDocs.remove( 0 );
+ }
+
+ m_aWikiDocs.add( aWikiDoc );
+ }
+
+
+ public Object[] getWikiDocList( int serverid )
+ {
+ String wikiserverurl = getWikiConUrlByNumber( serverid );
+ List<String> theDocs = new ArrayList<String>();
+ String [] docs = new String[0];
+ for ( int i=0; i<m_aWikiDocs.size(); i++ )
+ {
+ Map<String,Object> ht = m_aWikiDocs.get( i );
+ String docurl = ( String ) ht.get( "Url" );
+ if ( docurl.equals( wikiserverurl ) )
+ {
+ theDocs.add( (String ) ht.get( "Doc" ) );
+ }
+ }
+ return theDocs.toArray( docs );
+ }
+
+ public String[] getWikiURLs()
+ {
+ String [] WikiList = new String [m_WikiConnections.size()];
+ for ( int i=0; i<m_WikiConnections.size(); i++ )
+ {
+ Map<String,String> ht = m_WikiConnections.get( i );
+ WikiList[i] = ht.get( "Url" );
+ }
+ return WikiList;
+ }
+
+
+ public Map<String, String> getSettingByUrl( String sUrl )
+ {
+ Map<String, String> ht = null;
+ for( int i=0;i<m_WikiConnections.size();i++ )
+ {
+ Map<String, String> h1 = m_WikiConnections.get( i );
+ String u1 = h1.get( "Url" );
+ if ( u1.equals( sUrl ) )
+ {
+ ht = h1;
+ try
+ {
+ String sUserName = ht.get( "Username" );
+ String aPassword = ht.get( "Password" );
+ if ( sUserName != null && sUserName.length() > 0 && ( aPassword == null || aPassword.length() == 0 ) )
+ {
+ String[] pPasswords = Helper.GetPasswordsForURLAndUser( m_xContext, sUrl, sUserName );
+ if ( pPasswords != null && pPasswords.length > 0 )
+ ht.put( "Password", pPasswords[0] );
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ break;
+ }
+ }
+ return ht;
+ }
+
+ private Map<String,Object> getDocByCompleteUrl( String curl )
+ {
+ Map<String,Object> ht = null;
+ for( int i=0;i<m_aWikiDocs.size();i++ )
+ {
+ Map<String,Object> h1 = m_aWikiDocs.get( i );
+ String u1 = ( String ) h1.get( "CompleteUrl" );
+ if ( u1.equals( curl ) )
+ {
+ ht = h1;
+ }
+ }
+ return ht;
+ }
+
+
+ public void removeSettingByUrl( String sUrl )
+ {
+ for( int i=0;i<m_WikiConnections.size();i++ )
+ {
+ Map<String,String> h1 = m_WikiConnections.get( i );
+ String u1 = h1.get( "Url" );
+ if ( u1.equals( sUrl ) )
+ {
+ m_WikiConnections.remove( i );
+ }
+ }
+ }
+
+
+ public void storeConfiguration()
+ {
+ try
+ {
+ {
+ // remove stored connection information
+ XNameContainer xContainer = Helper.GetConfigNameContainer(m_xContext, "org.openoffice.Office.Custom.WikiExtension/ConnectionList");
+ String[] pNames = xContainer.getElementNames();
+ for (String pName : pNames)
+ {
+ xContainer.removeByName(pName);
+ }
+ // store all connections
+ XSingleServiceFactory xConnectionFactory = UnoRuntime.queryInterface(XSingleServiceFactory.class, xContainer);
+ for (Map<String, String> ht : m_WikiConnections)
+ {
+ Object oNewConnection = xConnectionFactory.createInstance();
+ XNameReplace xNewConn = UnoRuntime.queryInterface(XNameReplace.class, oNewConnection);
+ if (xNewConn != null)
+ {
+ xNewConn.replaceByName("UserName", ht.get("Username"));
+ }
+ xContainer.insertByName(ht.get("Url"), xNewConn);
+ }
+ // commit changes
+ XChangesBatch xBatch = UnoRuntime.queryInterface(XChangesBatch.class, xContainer);
+ xBatch.commitChanges();
+ }
+
+ {
+ // remove stored connection information
+ XNameContainer xContainer = Helper.GetConfigNameContainer(m_xContext, "org.openoffice.Office.Custom.WikiExtension/RecentDocs");
+ String[] pNames = xContainer.getElementNames();
+ for (String pName : pNames)
+ {
+ xContainer.removeByName(pName);
+ }
+ // store all Docs
+ XSingleServiceFactory xDocListFactory = UnoRuntime.queryInterface(XSingleServiceFactory.class, xContainer);
+ int i = 0;
+ for (Map<String, Object> ht : m_aWikiDocs)
+ {
+ Object oNewDoc = xDocListFactory.createInstance();
+ XNameReplace xNewDoc = UnoRuntime.queryInterface(XNameReplace.class, oNewDoc);
+ for (Map.Entry<String, Object> entry : ht.entrySet())
+ {
+ xNewDoc.replaceByName(entry.getKey(), entry.getValue());
+ }
+ xContainer.insertByName("d" + i++, xNewDoc);
+ }
+ // commit changes
+ XChangesBatch xBatch = UnoRuntime.queryInterface(XChangesBatch.class, xContainer);
+ xBatch.commitChanges();
+ }
+
+ }
+ catch ( Exception ex )
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ public void loadConfiguration()
+ {
+ m_WikiConnections.clear();
+ try
+ {
+ // get configuration service
+ // connect to configmanager
+ XNameAccess xAccess = Helper.GetConfigNameAccess( m_xContext, "org.openoffice.Office.Custom.WikiExtension" );
+
+ if ( xAccess != null )
+ {
+ Object oList = xAccess.getByName( "ConnectionList" );
+ XNameAccess xConnectionList = UnoRuntime.queryInterface( XNameAccess.class, oList );
+ String [] allCons = xConnectionList.getElementNames();
+ for (String aConnection : allCons)
+ {
+ Map<String, String> ht = new HashMap<String, String>();
+ ht.put("Url", aConnection);
+ ht.put( "Username", "" );
+ ht.put( "Password", "" );
+ try
+ {
+ XPropertySet xProps = UnoRuntime.queryInterface(XPropertySet.class, xConnectionList.getByName(aConnection));
+ if ( xProps != null )
+ {
+ String aUsername = AnyConverter.toString( xProps.getPropertyValue( "UserName" ) );
+ if ( aUsername != null && aUsername.length() > 0 )
+ ht.put( "Username", aUsername );
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ addWikiCon( ht );
+ }
+
+ Object oDocs = xAccess.getByName( "RecentDocs" );
+ XNameAccess xRecentDocs = UnoRuntime.queryInterface( XNameAccess.class, oDocs );
+ String [] allDocs = xRecentDocs.getElementNames();
+ for (String aDocument : allDocs)
+ {
+ Object oDoc = xRecentDocs.getByName(aDocument);
+ XNameAccess xDoc = UnoRuntime.queryInterface( XNameAccess.class, oDoc );
+ Map<String, Object> ht = new HashMap<String, Object>();
+ ht.put( "Url", xDoc.getByName( "Url" ) );
+ ht.put( "CompleteUrl", xDoc.getByName( "CompleteUrl" ) );
+ ht.put( "Doc", xDoc.getByName( "Doc" ) );
+ addWikiDoc( ht );
+ }
+ }
+ }
+ catch ( Exception ex )
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java b/swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java
new file mode 100644
index 0000000000..5c22afa2a6
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java
@@ -0,0 +1,261 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+import java.io.StringReader;
+import java.io.OutputStreamWriter;
+import java.util.Map;
+import java.net.URLEncoder;
+import java.net.URI;
+import java.net.HttpURLConnection;
+
+import javax.swing.text.html.HTMLEditorKit;
+
+import com.sun.star.uno.XComponentContext;
+
+
+public class WikiArticle
+{
+ private final XComponentContext m_xContext;
+
+ private String m_sEditTime = "";
+ private String m_sEditToken = "";
+
+ private String m_sHTMLCode;
+ private boolean m_bNoArticle = true;
+
+ private String m_sWikiUser;
+ private String m_sWikiPass;
+
+ private final String m_sTitle;
+
+ private final URI m_aMainURI;
+ private boolean m_isLoggedIn = false;
+
+ /** Creates a new instance of WikiArticle */
+ public WikiArticle( XComponentContext xContext, String sTitle, Map<String,String> wikiSettings, boolean bLogin, WikiPropDialog aPropDialog )
+ throws java.net.URISyntaxException, java.io.IOException, WikiCancelException
+ {
+ m_xContext = xContext;
+
+ String sMainUrl = wikiSettings.get("Url");
+ m_sWikiUser = wikiSettings.get("Username");
+ m_sWikiPass = wikiSettings.get("Password");
+ m_sTitle = sTitle;
+
+ m_aMainURI = new URI(sMainUrl);
+
+ if ( bLogin )
+ {
+ WikiEditSettingDialog aDialog = new WikiEditSettingDialog(m_xContext, "vnd.sun.star.script:WikiEditor.EditSetting?location=application", wikiSettings, false );
+ try
+ {
+ while( !Login() )
+ {
+ if ( aPropDialog != null )
+ aPropDialog.SetThrobberActive( false );
+
+ if ( MainThreadDialogExecutor.Show( xContext, aDialog ) )
+ {
+ m_sWikiUser = wikiSettings.get("Username");
+ m_sWikiPass = wikiSettings.get("Password");
+ }
+ else
+ throw new WikiCancelException();
+
+ if ( aPropDialog != null )
+ {
+ aPropDialog.SetThrobberActive( true );
+ Thread.yield();
+ }
+ }
+ }
+ finally
+ {
+ aDialog.DisposeDialog();
+ }
+ }
+
+ // in case of loading the html contents are used
+ // in case of saving the contents should be checked whether they are empty
+ InitArticleHTML();
+ }
+
+ public String GetMainURL()
+ {
+ return m_aMainURI.toString();
+ }
+
+ public String GetTitle()
+ {
+ return m_sTitle;
+ }
+
+
+
+ private String getArticleWiki()
+ throws java.net.URISyntaxException, java.io.IOException, WikiCancelException
+ {
+ String sWikiCode = null;
+
+ if (m_isLoggedIn)
+ {
+ URI aURI = new URI(m_aMainURI.toString() + "index.php?title=" + m_sTitle + "&action=edit");
+ HttpURLConnection connGet = Helper.PrepareMethod("GET", aURI, m_xContext);
+ connGet.connect();
+
+ int nResultCode = connGet.getResponseCode();
+ String sWebPage = null;
+ if (nResultCode == 200) {
+ sWebPage = Helper.ReadResponseBody(connGet);
+ }
+
+ if ( sWebPage != null )
+ {
+ StringReader r = new StringReader(sWebPage);
+ HTMLEditorKit.Parser parse = Helper.GetHTMLParser();
+ EditPageParser callback = new EditPageParser();
+
+ parse.parse(r,callback,true);
+ m_sEditTime = callback.m_sEditTime;
+ m_sEditToken = callback.m_sEditToken;
+
+ int iPosStart = callback.m_nWikiArticleStart;
+ int iPosEnd = callback.m_nWikiArticleEnd;
+
+ if ( iPosStart >= 0 && iPosEnd > 0 )
+ {
+ String sArticle = sWebPage.substring(iPosStart, iPosEnd);
+ iPosStart = sArticle.indexOf('>') + 1;
+ sWikiCode = sArticle.substring( iPosStart, sArticle.length() );
+ }
+ }
+ }
+
+ return sWikiCode;
+ }
+
+ private void InitArticleHTML()
+ throws java.net.URISyntaxException, java.io.IOException, WikiCancelException
+ {
+ if (m_isLoggedIn)
+ {
+ URI uri = new URI(m_aMainURI.toString() + "index.php?title=" + m_sTitle);
+ HttpURLConnection connGet = Helper.PrepareMethod("GET", uri, m_xContext);
+ connGet.connect();
+
+ int nResultCode = connGet.getResponseCode();
+ String sWebPage = null;
+ if (nResultCode == 200) {
+ sWebPage = Helper.ReadResponseBody(connGet);
+ }
+
+ if ( sWebPage != null )
+ {
+ StringReader r = new StringReader(sWebPage);
+ HTMLEditorKit.Parser parse = Helper.GetHTMLParser();
+ EditPageParser callback = new EditPageParser();
+
+ parse.parse(r,callback,true);
+
+ int iPosStart = callback.m_nHTMLArticleStart;
+ int iPosEnd = callback.m_nHTMLArticleEnd;
+ int nPosNoArt = callback.m_nNoArticleInd;
+
+ if ( iPosStart >= 0 && iPosEnd > 0 )
+ {
+ m_sHTMLCode = sWebPage.substring(iPosStart, iPosEnd);
+ m_bNoArticle = ( nPosNoArt >= 0 && nPosNoArt >= iPosStart && nPosNoArt <= iPosEnd );
+ }
+ }
+ }
+ }
+
+ protected boolean setArticle( String sWikiCode, String sWikiComment, boolean bMinorEdit )
+ throws java.net.URISyntaxException, java.io.IOException, WikiCancelException
+ {
+ boolean bResult = false;
+
+ if (m_isLoggedIn && sWikiCode != null && sWikiComment != null)
+ {
+ // get the edit time and token
+ getArticleWiki();
+
+ URI uri = new URI(m_aMainURI.toString() + "index.php?title=" + m_sTitle + "&action=submit");
+
+ HttpURLConnection connPost = Helper.PrepareMethod("POST", uri, m_xContext);
+ connPost.setDoInput(true);
+ connPost.setDoOutput(true);
+ connPost.connect();
+
+ OutputStreamWriter post = new OutputStreamWriter(connPost.getOutputStream(), "UTF-8");
+ try
+ {
+ post.write("wpTextbox1=");
+ post.write(URLEncoder.encode(sWikiCode, "UTF-8"));
+ post.write("&wpSummary=");
+ post.write(URLEncoder.encode(sWikiComment, "UTF-8"));
+ post.write("&wpSection=");
+ post.write("&wpEdittime=");
+ post.write(URLEncoder.encode(m_sEditTime, "UTF-8"));
+ post.write("&wpSave=Save%20page");
+ post.write("&wpEditToken=");
+ post.write(URLEncoder.encode(m_sEditToken, "UTF-8"));
+
+ if (bMinorEdit) {
+ post.write("&wpMinoredit=1");
+ }
+
+ post.flush();
+ }
+ finally
+ {
+ post.close();
+ }
+
+ int nResultCode = connPost.getResponseCode();
+ if ( nResultCode < 400 )
+ bResult = true;
+
+ String aResult = Helper.ReadResponseBody(connPost);
+
+ // TODO: remove the debug printing, try to detect the error
+ System.out.print( "nSubmitCode = " + nResultCode + "\n===\n" + aResult );
+ }
+
+ return bResult;
+ }
+
+ private boolean Login()
+ throws java.net.URISyntaxException, java.io.IOException, WikiCancelException
+ {
+ m_isLoggedIn = Helper.Login( m_aMainURI, m_sWikiUser, m_sWikiPass, m_xContext );
+ return m_isLoggedIn;
+ }
+
+ protected boolean NotExist()
+ {
+ boolean bResult = true;
+ if ( m_sHTMLCode != null )
+ bResult = m_bNoArticle;
+
+ return bResult;
+ }
+
+}
diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiCancelException.java b/swext/mediawiki/src/com/sun/star/wiki/WikiCancelException.java
new file mode 100644
index 0000000000..0a6c81ebe4
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/WikiCancelException.java
@@ -0,0 +1,24 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+class WikiCancelException extends java.lang.Exception
+{
+}
+
diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiDialog.java b/swext/mediawiki/src/com/sun/star/wiki/WikiDialog.java
new file mode 100644
index 0000000000..66bef678e4
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/WikiDialog.java
@@ -0,0 +1,283 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+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.XAnimation;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.awt.XTopWindow;
+import com.sun.star.awt.XTopWindowListener;
+import com.sun.star.awt.XWindow;
+import com.sun.star.container.XNameContainer;
+import com.sun.star.lang.EventObject;
+import com.sun.star.lang.XMultiServiceFactory;
+
+public class WikiDialog implements XDialogEventHandler, XTopWindowListener
+{
+ protected XComponentContext m_xContext;
+ private XControlContainer m_xControlContainer;
+ protected XDialog m_xDialog;
+ private String[] m_aMethods;
+ protected boolean m_bAction = false;
+ protected Settings m_aSettings;
+ protected Thread m_aThread;
+ protected boolean m_bThreadFinished = false;
+
+
+ /** Creates a new instance of WikiDialog */
+ public WikiDialog(XComponentContext c, String DialogURL)
+ {
+ this.m_xContext = c;
+ XMultiComponentFactory xMCF = m_xContext.getServiceManager();
+ m_aSettings = Settings.getSettings(m_xContext);
+ try
+ {
+ Object obj;
+ obj = xMCF.createInstanceWithContext("com.sun.star.awt.DialogProvider2", m_xContext );
+ XDialogProvider2 xDialogProvider = UnoRuntime.queryInterface( XDialogProvider2.class, obj );
+
+ m_xDialog = xDialogProvider.createDialogWithHandler( DialogURL, this );
+ m_xControlContainer = UnoRuntime.queryInterface( XControlContainer.class, m_xDialog );
+ XTopWindow xTopWindow = UnoRuntime.queryInterface( XTopWindow.class, m_xDialog );
+ if ( xTopWindow != null )
+ xTopWindow.addTopWindowListener( this );
+ }
+ catch (com.sun.star.uno.Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ public synchronized void ThreadStop( boolean bSelf )
+ {
+ if ( bSelf || m_aThread != null && !m_bThreadFinished )
+ {
+ try
+ {
+ Helper.AllowConnection( bSelf );
+ }
+ catch( Exception ex )
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ m_aThread = null;
+ m_bThreadFinished = true;
+ }
+
+ protected void setMethods (String [] Methods)
+ {
+ this.m_aMethods = Methods;
+ }
+
+
+ public boolean show( )
+ {
+ m_bThreadFinished = false;
+
+ if( m_xDialog != null ) m_xDialog.execute();
+ return m_bAction;
+ }
+
+
+ public String[] getSupportedMethodNames()
+ {
+ return m_aMethods;
+ }
+
+
+ public boolean callHandlerMethod( XDialog xDialog, Object EventObject, String MethodName )
+ {
+ return true;
+ }
+
+ public void SetTitle( String sTitle )
+ throws Exception
+ {
+ SetTitle( m_xDialog, sTitle );
+ }
+
+ private static void SetTitle( XDialog xDialog, String sTitle )
+ throws Exception
+ {
+ if ( xDialog == null || sTitle == null ) {
+ return;
+ }
+ XControl xDialogControl = UnoRuntime.queryInterface( XControl.class, xDialog );
+ if ( xDialogControl != null )
+ {
+ XPropertySet xPropSet = UnoRuntime.queryInterface( XPropertySet.class, xDialogControl.getModel() );
+ if ( xPropSet != null )
+ xPropSet.setPropertyValue( "Title", sTitle );
+ }
+ }
+
+ protected XPropertySet GetPropSet(String sControl)
+ {
+ return GetPropSet( m_xControlContainer, sControl );
+ }
+
+ private static XPropertySet GetPropSet( XControlContainer xControlContainer, String sControl )
+ {
+ XPropertySet xPS = null;
+
+ if ( xControlContainer != null && sControl != null )
+ {
+ XControl xControl = xControlContainer.getControl(sControl);
+ xPS = UnoRuntime.queryInterface(XPropertySet.class, xControl.getModel() );
+ }
+
+ if ( xPS == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ return xPS;
+ }
+
+
+
+ protected void InsertThrobber( int X, int Y, int Width, int Height )
+ {
+ try
+ {
+ XControl xDialogControl = UnoRuntime.queryInterface( XControl.class, m_xDialog );
+ XControlModel xDialogModel = null;
+ if ( xDialogControl != null )
+ xDialogModel = xDialogControl.getModel();
+
+ XMultiServiceFactory xDialogFactory = UnoRuntime.queryInterface( XMultiServiceFactory.class, xDialogModel );
+ if ( xDialogFactory != null )
+ {
+ XControlModel xThrobberModel = UnoRuntime.queryInterface( XControlModel.class, xDialogFactory.createInstance( "com.sun.star.awt.SpinningProgressControlModel" ) );
+ XPropertySet xThrobberProps = UnoRuntime.queryInterface( XPropertySet.class, xThrobberModel );
+ if ( xThrobberProps != null )
+ {
+ xThrobberProps.setPropertyValue( "Name", "WikiThrobber" );
+ xThrobberProps.setPropertyValue( "PositionX", Integer.valueOf( X ) );
+ xThrobberProps.setPropertyValue( "PositionY", Integer.valueOf( Y ) );
+ xThrobberProps.setPropertyValue( "Width", Integer.valueOf( Width ) );
+ xThrobberProps.setPropertyValue( "Height", Integer.valueOf( Height ) );
+
+ XNameContainer xDialogContainer = UnoRuntime.queryInterface( XNameContainer.class, xDialogModel );
+ xDialogContainer.insertByName( "WikiThrobber", xThrobberModel );
+ }
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ SetThrobberVisible( false );
+ }
+
+ public void SetThrobberActive( boolean bActive )
+ {
+ if ( m_xControlContainer != null )
+ {
+ try
+ {
+ XAnimation xThrobber = UnoRuntime.queryInterface( XAnimation.class, m_xControlContainer.getControl( "WikiThrobber" ) );
+ if ( xThrobber != null )
+ {
+ if ( bActive )
+ xThrobber.startAnimation();
+ else
+ xThrobber.stopAnimation();
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void SetThrobberVisible( boolean bVisible )
+ {
+ if ( m_xControlContainer != null )
+ {
+ try
+ {
+ XWindow xWindow = UnoRuntime.queryInterface( XWindow.class, m_xControlContainer.getControl( "WikiThrobber" ) );
+ if ( xWindow != null )
+ xWindow.setVisible( bVisible );
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void SetFocusTo( String aControl )
+ {
+ if ( m_xControlContainer != null )
+ {
+ try
+ {
+ XWindow xWindow = UnoRuntime.queryInterface( XWindow.class, m_xControlContainer.getControl( aControl ) );
+ if ( xWindow != null )
+ xWindow.setFocus();
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void DisposeDialog()
+ {
+ Helper.Dispose( m_xDialog );
+ }
+
+ public void windowOpened( EventObject e )
+ {}
+
+ public void windowClosing( EventObject e )
+ {}
+
+ public void windowClosed( EventObject e )
+ {}
+
+ public void windowMinimized( EventObject e )
+ {}
+
+ public void windowNormalized( EventObject e )
+ {}
+
+ public void windowActivated( EventObject e )
+ {}
+
+ public void windowDeactivated( EventObject e )
+ {}
+
+ public void disposing( EventObject e )
+ {}
+}
+
diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java b/swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java
new file mode 100644
index 0000000000..e1f1aac35d
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java
@@ -0,0 +1,416 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import java.net.URI;
+import java.net.HttpURLConnection;
+import javax.net.ssl.SSLException;
+
+import com.sun.star.awt.XDialog;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.EventObject;
+import com.sun.star.uno.XComponentContext;
+
+public class WikiEditSettingDialog extends WikiDialog
+{
+
+ private static final String sOKMethod = "OK";
+
+ private final String[] Methods = {sOKMethod };
+ private final Map<String,String> setting;
+ private final boolean addMode;
+ private boolean m_bAllowURLChange = true;
+
+ public WikiEditSettingDialog( XComponentContext xContext, String DialogURL )
+ {
+ super( xContext, DialogURL );
+ super.setMethods( Methods );
+ setting = new HashMap<String,String>();
+ addMode = true;
+
+ InsertThrobber( 184, 20, 10, 10 );
+ InitStrings( xContext );
+ InitSaveCheckbox( xContext, false );
+ }
+
+ public WikiEditSettingDialog( XComponentContext xContext, String DialogURL, Map<String,String> ht, boolean bAllowURLChange )
+ {
+ super( xContext, DialogURL );
+ super.setMethods( Methods );
+ setting = ht;
+
+ boolean bInitSaveCheckBox = false;
+
+ try
+ {
+ XPropertySet xUrlField = GetPropSet( "UrlField" );
+
+ xUrlField.setPropertyValue( "Text", ht.get( "Url" ) );
+
+ GetPropSet( "UsernameField" ).setPropertyValue( "Text", ht.get( "Username" ) );
+
+ if ( Helper.PasswordStoringIsAllowed( m_xContext ) )
+ {
+ String[] pPasswords = Helper.GetPasswordsForURLAndUser( m_xContext, ht.get( "Url" ), ht.get( "Username" ) );
+ bInitSaveCheckBox = ( pPasswords != null && pPasswords.length > 0 && pPasswords[0].equals( ht.get( "Password" ) ) );
+ }
+
+ // the password should be entered by the user or the Cancel should be pressed
+ // GetPropSet( "PasswordField" ).setPropertyValue( "Text", ht.get( "Password" ));
+ }
+ catch ( Exception ex )
+ {
+ ex.printStackTrace();
+ }
+
+ addMode = false;
+ m_bAllowURLChange = bAllowURLChange;
+
+ InsertThrobber( 184, 20, 10, 10 );
+ InitStrings( xContext );
+ InitSaveCheckbox( xContext, bInitSaveCheckBox );
+ }
+
+ @Override
+ public boolean show( )
+ {
+ SetThrobberVisible( false );
+ EnableControls( true );
+ boolean bResult = super.show();
+
+ try
+ {
+ if ( bResult && Helper.PasswordStoringIsAllowed( m_xContext )
+ && ( (Short)( GetPropSet( "SaveBox" ).getPropertyValue("State") ) ).shortValue() != (short)0 )
+ {
+ String sURL = setting.get( "Url" );
+ String sUserName = setting.get( "Username" );
+ String sPassword = setting.get( "Password" );
+
+ if ( sURL != null && sURL.length() > 0 && sUserName != null && sUserName.length() > 0 && sPassword != null && sPassword.length() > 0 )
+ {
+ String[] pPasswords = { sPassword };
+ Helper.GetPasswordContainer( m_xContext ).addPersistent( sURL, sUserName, pPasswords, Helper.GetInteractionHandler( m_xContext ) );
+ }
+ }
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ return bResult;
+ }
+
+ private void EnableControls( boolean bEnable )
+ {
+ if ( !bEnable )
+ SetFocusTo( "CancelButton" );
+
+ try
+ {
+ GetPropSet( "UsernameField" ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) );
+ GetPropSet( "PasswordField" ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) );
+ GetPropSet( "OkButton" ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) );
+ GetPropSet( "HelpButton" ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) );
+
+ if ( bEnable )
+ {
+ GetPropSet( "UrlField" ).setPropertyValue( "Enabled", Boolean.valueOf( m_bAllowURLChange ) );
+ GetPropSet( "SaveBox" ).setPropertyValue( "Enabled", Boolean.valueOf( Helper.PasswordStoringIsAllowed( m_xContext ) ) );
+ if ( m_bAllowURLChange )
+ SetFocusTo( "UrlField" );
+ else
+ SetFocusTo( "UsernameField" );
+ }
+ else
+ {
+ GetPropSet( "UrlField" ).setPropertyValue( "Enabled", Boolean.FALSE );
+ GetPropSet( "SaveBox" ).setPropertyValue( "Enabled", Boolean.FALSE );
+ }
+ }
+ catch ( Exception ex )
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ private void InitStrings( XComponentContext xContext )
+ {
+ try
+ {
+ SetTitle( Helper.GetLocalizedString( xContext, Helper.DLG_MEDIAWIKI_TITLE ) );
+ GetPropSet( "UrlLabel" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_URLLABEL ) );
+ GetPropSet( "UsernameLabel" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_USERNAMELABEL ) );
+ GetPropSet( "PasswordLabel" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_PASSWORDLABEL ) );
+ GetPropSet( "AccountLine" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_ACCOUNTLINE ) );
+ GetPropSet( "WikiLine" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_WIKILINE ) );
+ GetPropSet( "SaveBox" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_EDITSETTING_SAVEBOX ) );
+ GetPropSet( "OkButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_OK ) );
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void InitSaveCheckbox( XComponentContext xContext, boolean bInitSaveCheckBox )
+ {
+ XPropertySet xSaveCheck = GetPropSet( "SaveBox" );
+ try
+ {
+ xSaveCheck.setPropertyValue( "State", Short.valueOf( bInitSaveCheckBox ? (short)1 : (short)0 ) );
+ xSaveCheck.setPropertyValue( "Enabled", Boolean.valueOf( Helper.PasswordStoringIsAllowed( xContext ) ) );
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void DoLogin()
+ {
+ String sRedirectURL = "";
+ String sURL = "";
+ try
+ {
+ sURL = ( String ) GetPropSet( "UrlField" ).getPropertyValue( "Text" );
+ String sUserName = ( String ) GetPropSet( "UsernameField" ).getPropertyValue( "Text" );
+ String sPassword = ( String ) GetPropSet( "PasswordField" ).getPropertyValue( "Text" );
+
+ boolean bAllowIndex = true;
+
+ do
+ {
+ if ( sRedirectURL.length() > 0 )
+ {
+ sURL = sRedirectURL;
+ sRedirectURL = "";
+ }
+
+ if ( sURL.length() > 0 )
+ {
+ URI aURI = new URI(sURL);
+ HttpURLConnection connGet = Helper.PrepareMethod("GET", aURI, m_xContext);
+ connGet.setInstanceFollowRedirects(false);
+ connGet.connect();
+
+ int nResultCode = connGet.getResponseCode();
+ String sWebPage = null;
+ if ( nResultCode == 200 )
+ sWebPage = Helper.ReadResponseBody(connGet);
+ else if ( nResultCode >= 301 && nResultCode <= 303 || nResultCode == 307 )
+ sRedirectURL = connGet.getHeaderField("Location");
+
+ if ( sWebPage != null && sWebPage.length() > 0 )
+ {
+ //the URL is valid
+ String sMainURL = Helper.GetMainURL( sWebPage, sURL );
+
+ if ( sMainURL.length() == 0 )
+ {
+ // TODO:
+ // it's not a Wiki Page, check first whether a redirect is requested
+ // happens usually in case of https
+ sRedirectURL = Helper.GetRedirectURL( sWebPage, sURL );
+ if ( sRedirectURL.length() == 0 )
+ {
+ // show error
+ Helper.ShowError( m_xContext,
+ m_xDialog,
+ Helper.DLG_MEDIAWIKI_TITLE,
+ Helper.NOURLCONNECTION_ERROR,
+ sURL,
+ false );
+ }
+ }
+ else
+ {
+ URI aMainURI = new URI(sMainURL);
+
+ if ( ( sUserName.length() > 0 || sPassword.length() > 0 )
+ && !Helper.Login(aMainURI, sUserName, sPassword, m_xContext))
+ {
+ // a wrong login information is provided
+ // show error
+ Helper.ShowError( m_xContext,
+ m_xDialog,
+ Helper.DLG_MEDIAWIKI_TITLE,
+ Helper.WRONGLOGIN_ERROR,
+ null,
+ false );
+ }
+ else
+ {
+ setting.put( "Url", aMainURI.toASCIIString() );
+ setting.put( "Username", sUserName );
+ setting.put( "Password", sPassword );
+ if ( addMode )
+ {
+ // no cleaning of the settings is necessary
+ Settings.getSettings( m_xContext ).addWikiCon( setting );
+ Settings.getSettings( m_xContext ).storeConfiguration();
+ }
+
+ m_bAction = true;
+ }
+ }
+ }
+ else if ( sRedirectURL == null || sRedirectURL.length() == 0 )
+ {
+ if ( sURL.length() > 0 && !sURL.endsWith( "index.php" ) && bAllowIndex )
+ {
+ // the used MainURL is not always directly accessible
+ // add the suffix as workaround, but only once
+ sRedirectURL = sURL + "/index.php";
+ bAllowIndex = false;
+ }
+ else
+ {
+ // URL invalid
+ // show error
+ Helper.ShowError( m_xContext,
+ m_xDialog,
+ Helper.DLG_MEDIAWIKI_TITLE,
+ Helper.INVALIDURL_ERROR,
+ null,
+ false );
+ }
+ }
+ }
+ else
+ {
+ // URL field empty
+ // show error
+ Helper.ShowError( m_xContext,
+ m_xDialog,
+ Helper.DLG_MEDIAWIKI_TITLE,
+ Helper.NOURL_ERROR,
+ null,
+ false );
+ }
+ } while (sRedirectURL != null && sRedirectURL.length() > 0);
+ }
+ catch ( WikiCancelException ce )
+ {
+ }
+ catch ( SSLException essl )
+ {
+ if ( Helper.IsConnectionAllowed() )
+ {
+ Helper.ShowError( m_xContext,
+ m_xDialog,
+ Helper.DLG_MEDIAWIKI_TITLE,
+ Helper.UNKNOWNCERT_ERROR,
+ null,
+ false );
+ }
+ essl.printStackTrace();
+ }
+ catch ( Exception ex )
+ {
+ if ( Helper.IsConnectionAllowed() )
+ {
+ Helper.ShowError( m_xContext,
+ m_xDialog,
+ Helper.DLG_MEDIAWIKI_TITLE,
+ Helper.NOURLCONNECTION_ERROR,
+ sURL,
+ false );
+ }
+ ex.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean callHandlerMethod( XDialog xDialog, Object EventObject, String MethodName )
+ {
+ if ( MethodName.equals( sOKMethod ) )
+ {
+ EnableControls( false );
+ SetThrobberVisible( true );
+ SetThrobberActive( true );
+
+ if ( Helper.AllowThreadUsage( m_xContext ) )
+ {
+ final XDialog xDialogForThread = xDialog;
+ final XComponentContext xContext = m_xContext;
+
+ // the thread name is used to allow the error dialogs
+ m_bThreadFinished = false;
+ m_aThread = new Thread( "com.sun.star.thread.WikiEditorSendingThread" )
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ Thread.yield();
+ } catch( java.lang.Exception e ){}
+
+ DoLogin();
+ WikiEditSettingDialog.this.EnableControls( true );
+ WikiEditSettingDialog.this.SetThrobberActive( false );
+ WikiEditSettingDialog.this.SetThrobberVisible( false );
+
+ ThreadStop( true );
+
+ if ( m_bAction )
+ MainThreadDialogExecutor.Close( xContext, xDialogForThread );
+ }
+ };
+
+ m_aThread.start();
+ }
+ else
+ {
+ try
+ {
+ DoLogin();
+ } catch( java.lang.Exception e )
+ {}
+ finally
+ {
+ EnableControls( true );
+ SetThrobberActive( false );
+ SetThrobberVisible( false );
+
+ if ( m_bAction )
+ xDialog.endExecute();
+
+ Helper.AllowConnection( true );
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void windowClosed( EventObject e )
+ {
+ ThreadStop( false );
+ }
+}
+
diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiEditorImpl.java b/swext/mediawiki/src/com/sun/star/wiki/WikiEditorImpl.java
new file mode 100644
index 0000000000..3d1bee21e7
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/WikiEditorImpl.java
@@ -0,0 +1,353 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+import java.io.File;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.net.ssl.SSLException;
+
+import com.sun.star.awt.XWindowPeer;
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.frame.DispatchDescriptor;
+import com.sun.star.frame.XController;
+import com.sun.star.frame.XDispatch;
+import com.sun.star.frame.XDispatchProvider;
+import com.sun.star.frame.XFrame;
+import com.sun.star.frame.XModel;
+import com.sun.star.frame.XStorable;
+import com.sun.star.lang.XInitialization;
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lib.uno.helper.Factory;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+
+
+public final class WikiEditorImpl extends WeakBase
+ implements com.sun.star.lang.XServiceInfo, XDispatchProvider, XDispatch, XInitialization
+{
+
+ private static final String m_implementationName = WikiEditorImpl.class.getName();
+ private static final String[] m_serviceNames = {"com.sun.star.wiki.WikiEditor" };
+
+
+
+ // protocol name that this protocol handler handles
+ private static final String protocolName = "vnd.com.sun.star.wiki:";
+
+ private final XComponentContext m_xContext;
+ private XFrame m_xFrame;
+ private XModel m_xModel;
+ private final Settings m_aSettings;
+ private String m_aFilterName;
+
+ public WikiEditorImpl( XComponentContext xContext )
+ {
+ // Helper.trustAllSSL();
+ m_xContext = xContext;
+ m_aSettings = Settings.getSettings( m_xContext );
+ }
+
+ public static XSingleComponentFactory __getComponentFactory( String sImplementationName )
+ {
+ XSingleComponentFactory xFactory = null;
+
+ if ( sImplementationName.equals( m_implementationName ) )
+ xFactory = Factory.createComponentFactory( WikiEditorImpl.class, m_serviceNames );
+ else if ( sImplementationName.equals( WikiOptionsEventHandlerImpl.m_sImplementationName ) )
+ xFactory = Factory.createComponentFactory( WikiOptionsEventHandlerImpl.class,
+ WikiOptionsEventHandlerImpl.m_pServiceNames );
+
+ return xFactory;
+ }
+
+ // 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;
+ }
+
+
+ public synchronized void initialize( Object[] args ) throws com.sun.star.uno.Exception
+ {
+ if ( args.length > 0 )
+ {
+ m_xFrame = UnoRuntime.queryInterface( XFrame.class, args[0] );
+ }
+ }
+
+
+
+ public void dispatch(
+ final com.sun.star.util.URL aURL,
+ com.sun.star.beans.PropertyValue[] propertyValue )
+ {
+ final com.sun.star.util.URL myURL = aURL;
+ if ( aURL.Protocol.equals(protocolName) )
+ {
+ try
+ {
+ if ( myURL.Path.equals("send") )
+ {
+ sendArticle();
+ }
+ } catch( java.lang.Throwable t )
+ {
+ }
+ }
+ }
+
+
+ public com.sun.star.frame.XDispatch queryDispatch(
+ com.sun.star.util.URL aURL,
+ String str,
+ int param )
+ {
+ if ( aURL.Protocol.equals( protocolName ))
+ {
+
+ // by default, we are responsible
+ return this;
+ } else
+ {
+ return null;
+ }
+ }
+
+ public XDispatch[] queryDispatches( DispatchDescriptor[] seqDescripts )
+ {
+ int nCount = seqDescripts.length;
+ XDispatch[] lDispatcher = new XDispatch[nCount];
+
+ for( int i=0; i<nCount; ++i )
+ lDispatcher[i] = queryDispatch(
+ seqDescripts[i].FeatureURL,
+ seqDescripts[i].FrameName,
+ seqDescripts[i].SearchFlags );
+ return lDispatcher;
+ }
+
+
+ public void removeStatusListener(
+ com.sun.star.frame.XStatusListener xStatusListener,
+ com.sun.star.util.URL aURL )
+ {
+ }
+
+
+ public void addStatusListener(
+ com.sun.star.frame.XStatusListener listener,
+ com.sun.star.util.URL url )
+ {
+ }
+
+ private void sendArticle()
+ {
+ if ( m_xFrame != null )
+ {
+ WikiPropDialog aSendDialog = null;
+ try
+ {
+ if ( m_xModel == null )
+ {
+ XController xController = m_xFrame.getController();
+ if ( xController != null )
+ m_xModel = xController.getModel();
+ }
+
+ if ( m_xModel != null )
+ {
+ // The related Wiki filter must be detected from the typename
+ String aServiceName = Helper.GetDocServiceName( m_xContext, m_xModel );
+ m_aFilterName = Helper.GetFilterName( m_xContext, "MediaWiki", aServiceName );
+
+ if ( m_aFilterName == null || m_aFilterName.length() == 0 )
+ {
+ Helper.ShowError( m_xContext,
+ UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ),
+ Helper.DLG_SENDTITLE,
+ Helper.NOWIKIFILTER_ERROR,
+ null,
+ false );
+ throw new com.sun.star.uno.RuntimeException();
+ }
+
+ m_aSettings.loadConfiguration(); // throw away all the noncommitted changes
+ // show the send dialog
+ aSendDialog = new WikiPropDialog( m_xContext, "vnd.sun.star.script:WikiEditor.SendToMediaWiki?location=application", this );
+ aSendDialog.fillWikiList();
+ aSendDialog.SetWikiTitle( Helper.GetDocTitle( m_xModel ) );
+ aSendDialog.show(); // triggers the sending
+ }
+ }
+ catch ( Exception e )
+ {
+ // TODO: Error handling here
+ e.printStackTrace();
+ }
+ finally
+ {
+ if ( aSendDialog != null )
+ aSendDialog.DisposeDialog();
+ }
+ }
+ }
+
+ public boolean SendArticleImpl( WikiPropDialog aSendDialog, Map<String,String> aWikiSetting )
+ {
+ boolean bResult = false;
+
+ if ( aSendDialog != null )
+ {
+ String sTemp2Url = null;
+
+ try
+ {
+ // TODO: stop progress spinning
+ WikiArticle aArticle = new WikiArticle( m_xContext, aSendDialog.GetWikiTitle(), aWikiSetting, true, aSendDialog );
+
+ boolean bAllowSending = true;
+ if ( !aArticle.NotExist() )
+ {
+ // ask whether creation of a new page is allowed
+ aSendDialog.SetThrobberActive( false );
+ bAllowSending = Helper.ShowError(
+ m_xContext,
+ UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ),
+ Helper.DLG_SENDTITLE,
+ Helper.DLG_WIKIPAGEEXISTS_LABEL1,
+ aSendDialog.GetWikiTitle(),
+ true );
+ aSendDialog.SetThrobberActive( true );
+ }
+
+ if ( bAllowSending )
+ {
+ PropertyValue[] lProperties = new PropertyValue[2];
+ lProperties[0] = new PropertyValue();
+ lProperties[0].Name = "FilterName";
+ lProperties[0].Value = m_aFilterName;
+ lProperties[1] = new PropertyValue();
+ lProperties[1].Name = "Overwrite";
+ lProperties[1].Value = Boolean.TRUE;
+
+ sTemp2Url = Helper.CreateTempFile( m_xContext );
+
+ XStorable xStore = UnoRuntime.queryInterface ( XStorable.class, m_xModel );
+ if ( xStore == null )
+ throw new com.sun.star.uno.RuntimeException();
+
+ xStore.storeToURL( sTemp2Url, lProperties );
+ String sWikiCode = Helper.EachLine( sTemp2Url );
+
+ if ( aArticle.setArticle( sWikiCode, aSendDialog.m_sWikiComment, aSendDialog.m_bWikiMinorEdit ) )
+ {
+ bResult = true;
+ Helper.SetDocTitle( m_xModel, aArticle.GetTitle() );
+ Map<String,Object> aDocInfo = new HashMap<String,Object>();
+ aDocInfo.put( "Doc", aArticle.GetTitle() );
+ aDocInfo.put( "Url", aArticle.GetMainURL() );
+ aDocInfo.put( "CompleteUrl", aArticle.GetMainURL() + aArticle.GetTitle() );
+ m_aSettings.addWikiDoc( aDocInfo );
+ m_aSettings.storeConfiguration();
+ }
+ else
+ {
+ Helper.ShowError( m_xContext,
+ UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ),
+ Helper.DLG_SENDTITLE,
+ Helper.GENERALSEND_ERROR,
+ null,
+ false );
+ }
+ }
+ }
+ catch( WikiCancelException ec )
+ {
+ // nothing to do, the sending was cancelled
+ }
+ catch( SSLException essl )
+ {
+ if ( Helper.IsConnectionAllowed() )
+ {
+ // report the error only if sending was not cancelled
+ Helper.ShowError( m_xContext,
+ UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ),
+ Helper.DLG_SENDTITLE,
+ Helper.UNKNOWNCERT_ERROR,
+ null,
+ false );
+ }
+ }
+ catch( Exception e )
+ {
+ if ( Helper.IsConnectionAllowed() )
+ {
+ // report the error only if sending was not cancelled
+ Helper.ShowError( m_xContext,
+ UnoRuntime.queryInterface( XWindowPeer.class, m_xFrame.getContainerWindow() ),
+ Helper.DLG_SENDTITLE,
+ Helper.GENERALSEND_ERROR,
+ null,
+ false );
+ }
+ e.printStackTrace();
+ }
+
+ if ( sTemp2Url != null )
+ {
+ try
+ {
+ // remove the temporary file
+ File aFile = new File( new URI( sTemp2Url ) );
+ if (!aFile.delete()) {
+ throw new java.lang.Exception("could not remove" + sTemp2Url);
+ }
+ }
+ catch ( java.lang.Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return bResult;
+ }
+
+}
diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiOptionsEventHandlerImpl.java b/swext/mediawiki/src/com/sun/star/wiki/WikiOptionsEventHandlerImpl.java
new file mode 100644
index 0000000000..c35246be4d
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/WikiOptionsEventHandlerImpl.java
@@ -0,0 +1,279 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+import com.sun.star.awt.XContainerWindowEventHandler;
+import com.sun.star.awt.XControl;
+import com.sun.star.awt.XControlContainer;
+import com.sun.star.awt.XDialog;
+import com.sun.star.awt.XDialogEventHandler;
+import com.sun.star.awt.XWindow;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import java.util.Map;
+
+public final class WikiOptionsEventHandlerImpl extends WeakBase
+ implements XServiceInfo, XContainerWindowEventHandler, XDialogEventHandler
+{
+ static final String[] m_pServiceNames = { "com.sun.star.wiki.WikiOptionsEventHandler" };
+ static final String m_sImplementationName = WikiOptionsEventHandlerImpl.class.getName();
+
+ private static final String sExternalEvent = "external_event";
+ private static final String sAdd = "Add";
+ private static final String sEdit = "Edit";
+ private static final String sRemove = "Remove";
+ private static final String sListStatus = "ListStatus";
+ private static final String sListEdit = "ListEdit";
+ private static final String sInitialize = "initialize";
+ private static final String sOk = "ok";
+ private static final String sBack = "back";
+
+ private final XComponentContext m_xContext;
+ private XDialog m_xDialog;
+ private XControlContainer m_xControlContainer;
+
+ private Settings m_aSettings;
+
+ public WikiOptionsEventHandlerImpl( XComponentContext xContext )
+ {
+ m_xContext = xContext;
+ }
+
+ private XPropertySet GetPropSet( String sControl )
+ {
+ if ( m_xControlContainer != null )
+ {
+ XControl xControl = m_xControlContainer.getControl(sControl);
+ XPropertySet xListProps = UnoRuntime.queryInterface(XPropertySet.class, xControl.getModel() );
+ return xListProps;
+ }
+
+ return null;
+ }
+
+ private void RefreshView()
+ {
+ if ( m_aSettings != null )
+ {
+ String[] pWikiList = m_aSettings.getWikiURLs();
+ XPropertySet xListProps = GetPropSet( "WikiList" );
+ if ( xListProps != null )
+ {
+ try
+ {
+ xListProps.setPropertyValue( "StringItemList", pWikiList );
+ }
+ catch ( Exception ex )
+ {
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void CheckButtonState()
+ {
+ XPropertySet xListProps = GetPropSet( "WikiList" );
+ if ( xListProps != null )
+ {
+ try
+ {
+ short [] pSel = (short []) xListProps.getPropertyValue( "SelectedItems" );
+ XPropertySet xEditProps = GetPropSet( "EditButton" );
+ XPropertySet xRemoveProps = GetPropSet( "RemoveButton" );
+ Boolean bState = Boolean.valueOf( pSel.length != 0 );
+
+ xEditProps.setPropertyValue( "Enabled", bState );
+ xRemoveProps.setPropertyValue( "Enabled", bState );
+ }
+ catch ( Exception ex )
+ {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ private void AddSetting()
+ {
+ WikiEditSettingDialog aSettingDialog = new WikiEditSettingDialog( m_xContext, "vnd.sun.star.script:WikiEditor.EditSetting?location=application" );
+ if ( aSettingDialog.show() )
+ RefreshView();
+
+ aSettingDialog.DisposeDialog();
+ }
+
+ private void EditSetting()
+ {
+ XPropertySet xListProps = GetPropSet( "WikiList" );
+ if ( xListProps != null )
+ {
+ Map<String,String> ht = null;
+ try
+ {
+ short[] pSel = (short []) xListProps.getPropertyValue( "SelectedItems" );
+ String[] pItems = (String []) xListProps.getPropertyValue("StringItemList");
+ if ( pSel.length > 0 && pItems.length > pSel[0] )
+ {
+ String selName = pItems[pSel[0]];
+ ht = m_aSettings.getSettingByUrl( selName );
+ }
+ }
+ catch ( Exception ex )
+ {
+ ex.printStackTrace();
+ }
+
+ WikiEditSettingDialog aSettingDialog = new WikiEditSettingDialog(m_xContext, "vnd.sun.star.script:WikiEditor.EditSetting?location=application", ht, true );
+ if ( aSettingDialog.show() )
+ RefreshView();
+
+ aSettingDialog.DisposeDialog();
+ }
+ }
+
+ private void RemoveSetting()
+ {
+ XPropertySet xListProps = GetPropSet("WikiList");
+ if ( xListProps != null )
+ {
+ try
+ {
+ short[] pSel = (short []) xListProps.getPropertyValue("SelectedItems");
+ String[] pItems = (String []) GetPropSet("WikiList").getPropertyValue("StringItemList");
+ if ( pSel.length > 0 && pItems.length > pSel[0] )
+ {
+ m_aSettings.removeSettingByUrl( pItems[pSel[0]] );
+ RefreshView();
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ private void InitStrings()
+ {
+ try
+ {
+ GetPropSet( "FixedLine1" ).setPropertyValue( "Label", Helper.GetLocalizedString( m_xContext, Helper.DLG_MEDIAWIKIEXTENSION_STRING ) );
+ GetPropSet( "AddButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( m_xContext, Helper.DLG_ADDBUTTON ) );
+ GetPropSet( "EditButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( m_xContext, Helper.DLG_EDITBUTTON ) );
+ GetPropSet( "RemoveButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( m_xContext, Helper.DLG_REMOVEBUTTON ) );
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ // com.sun.star.lang.XServiceInfo:
+ public String getImplementationName()
+ {
+ return m_sImplementationName;
+ }
+
+ public boolean supportsService( String sService )
+ {
+ int len = m_pServiceNames.length;
+
+ for( int i=0; i < len; i++ )
+ {
+ if ( sService.equals( m_pServiceNames[i] ))
+ return true;
+ }
+ return false;
+ }
+
+ public String[] getSupportedServiceNames()
+ {
+ return m_pServiceNames;
+ }
+
+ // XContainerWindowEventHandler
+ public boolean callHandlerMethod( XWindow xWindow, Object aEventObject, String sMethod )
+ throws WrappedTargetException, com.sun.star.uno.RuntimeException
+ {
+ if ( sMethod.equals( sExternalEvent ) )
+ {
+ String sEvent = AnyConverter.toString( aEventObject );
+ if ( sEvent != null )
+ {
+ if ( sEvent.equals( sOk ) )
+ {
+ if ( m_aSettings != null )
+ m_aSettings.storeConfiguration();
+ }
+ else if ( sEvent.equals( sInitialize ) || sEvent.equals( sBack ) )
+ {
+ if ( sEvent.equals( sInitialize ) )
+ {
+ m_xDialog = UnoRuntime.queryInterface( XDialog.class, xWindow );
+ m_xControlContainer = UnoRuntime.queryInterface( XControlContainer.class, m_xDialog );
+ m_aSettings = Settings.getSettings( m_xContext );
+ m_aSettings.loadConfiguration(); // throw away all the noncommitted changes
+ InitStrings();
+ }
+ else if ( m_aSettings != null )
+ m_aSettings.loadConfiguration(); // throw away all the noncommitted changes
+
+ RefreshView();
+ CheckButtonState();
+ }
+ }
+ }
+ else if ( sMethod.equals( sAdd ) )
+ {
+ AddSetting();
+ }
+ else if ( sMethod.equals( sEdit ) || sMethod.equals( sListEdit ) )
+ {
+ EditSetting();
+ }
+ else if ( sMethod.equals( sRemove ) )
+ {
+ RemoveSetting();
+ CheckButtonState();
+ }
+ else if ( sMethod.equals( sListStatus ) )
+ {
+ CheckButtonState();
+ }
+
+ return true;
+ }
+
+ public boolean callHandlerMethod( XDialog xDialog, Object aEventObject, String sMethod )
+ throws WrappedTargetException, com.sun.star.uno.RuntimeException
+ {
+ return true;
+ }
+
+ public String[] getSupportedMethodNames()
+ {
+ return new String[] { sExternalEvent, sAdd, sEdit, sRemove };
+ }
+}
+
diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiPropDialog.java b/swext/mediawiki/src/com/sun/star/wiki/WikiPropDialog.java
new file mode 100644
index 0000000000..9ac41d4d31
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/WikiPropDialog.java
@@ -0,0 +1,372 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+import java.util.Map;
+
+import com.sun.star.awt.XDialog;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.EventObject;
+import com.sun.star.uno.XComponentContext;
+
+public class WikiPropDialog extends WikiDialog{
+
+ private WikiEditorImpl m_aWikiEditor;
+
+ private static final String sSendMethod = "Send";
+ private static final String sWikiListMethod = "WikiListChange";
+ private static final String sArticleTextMethod = "ArticleTextChange";
+ private static final String sAddWikiMethod = "AddWiki";
+
+ private final String[] m_pMethods = {sSendMethod, sWikiListMethod, sArticleTextMethod, sAddWikiMethod};
+
+ private String m_sWikiTitle = "";
+ private String m_sWikiEngineURL = "";
+ protected String m_sWikiComment = "";
+ protected boolean m_bWikiMinorEdit = false;
+
+ /** Creates a new instance of WikiPropDialog */
+ public WikiPropDialog(XComponentContext xContext, String DialogURL, WikiEditorImpl aWikiEditorForThrobber )
+ {
+ super(xContext, DialogURL);
+ super.setMethods(m_pMethods);
+
+ if ( aWikiEditorForThrobber != null )
+ {
+ InsertThrobber( 224, 122, 10, 10 );
+ m_aWikiEditor = aWikiEditorForThrobber;
+ }
+
+ InitStrings( xContext );
+ InitShowBrowser();
+ InitControls();
+ }
+
+ private void InitControls()
+ {
+ try
+ {
+ GetPropSet( "CommentText" ).setPropertyValue( "AutoVScroll", Boolean.TRUE );
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void InitStrings( XComponentContext xContext )
+ {
+ try
+ {
+ SetTitle( Helper.GetLocalizedString( xContext, Helper.DLG_SENDTITLE ) );
+ GetPropSet( "Label1" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDTOMEDIAWIKI_LABEL1 ) );
+ GetPropSet( "FixedLine2" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_WIKIARTICLE ) );
+ GetPropSet( "Label2" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDTOMEDIAWIKI_LABEL2 ) );
+ GetPropSet( "Label3" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDTOMEDIAWIKI_LABEL3 ) );
+ GetPropSet( "MinorCheck" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDTOMEDIAWIKI_MINORCHECK ) );
+ GetPropSet( "BrowserCheck" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDTOMEDIAWIKI_BROWSERCHECK ) );
+ GetPropSet( "AddButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_ADDBUTTON ) );
+ GetPropSet( "SendButton" ).setPropertyValue( "Label", Helper.GetLocalizedString( xContext, Helper.DLG_SENDBUTTON ) );
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void InitShowBrowser()
+ {
+ try
+ {
+ GetPropSet( "BrowserCheck" ).setPropertyValue( "State", Short.valueOf( Helper.GetShowInBrowserByDefault( m_xContext ) ? (short)1 : (short)0 ) );
+ }
+ catch( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean show()
+ {
+ EnableControls( true );
+ boolean bResult = super.show();
+
+ if ( bResult && Helper.GetShowInBrowserByDefault( m_xContext ) )
+ Helper.ShowURLInBrowser( m_xContext, m_sWikiEngineURL + "index.php?title=" + m_sWikiTitle );
+
+ return bResult;
+ }
+
+ @Override
+ public synchronized void ThreadStop( boolean bSelf )
+ {
+ boolean bShowError = ( !bSelf && m_aThread != null && !m_bThreadFinished );
+
+ super.ThreadStop( bSelf );
+
+ if ( bShowError )
+ Helper.ShowError( m_xContext,
+ m_xDialog,
+ Helper.DLG_SENDTITLE,
+ Helper.CANCELSENDING_ERROR,
+ null,
+ false );
+ }
+
+ public void fillWikiList()
+ {
+ String [] WikiList = m_aSettings.getWikiURLs();
+
+ try
+ {
+ XPropertySet xPS = GetPropSet("WikiList");
+ xPS.setPropertyValue("StringItemList", WikiList);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ private void fillDocList()
+ {
+ XPropertySet xPS = GetPropSet("ArticleText");
+ try
+ {
+ short [] sel = (short[]) GetPropSet("WikiList").getPropertyValue("SelectedItems");
+ xPS.setPropertyValue("StringItemList", m_aSettings.getWikiDocList(sel[0]));
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+
+ public String GetWikiTitle()
+ {
+ return m_sWikiTitle;
+ }
+
+ public void SetWikiTitle(String sArticle)
+ {
+ m_sWikiTitle = sArticle;
+ try
+ {
+ XPropertySet xPS = GetPropSet("ArticleText");
+ xPS.setPropertyValue("Text", sArticle);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+
+ private void switchSendButtonIfNecessary()
+ {
+ XPropertySet xSendButton = GetPropSet( "SendButton" );
+ if ( xSendButton != null )
+ {
+ XPropertySet xWikiListProps = GetPropSet( "WikiList" );
+ XPropertySet xArticleProps = GetPropSet( "ArticleText" );
+ if ( xWikiListProps != null && xArticleProps != null )
+ {
+ try
+ {
+ short [] pSel = (short[]) GetPropSet("WikiList").getPropertyValue("SelectedItems");
+ String sArticle = (String)xArticleProps.getPropertyValue( "Text" );
+ if ( pSel != null && pSel.length > 0 && sArticle != null && sArticle.length() != 0 )
+ xSendButton.setPropertyValue( "Enabled", Boolean.TRUE );
+ else
+ xSendButton.setPropertyValue( "Enabled", Boolean.FALSE );
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void EnableControls( boolean bEnable )
+ {
+ try
+ {
+ String[] pControls = { "WikiList",
+ "ArticleText",
+ "CommentText",
+ "MinorCheck",
+ "BrowserCheck",
+ "HelpButton",
+ "AddButton" };
+
+ for ( int nInd = 0; nInd < pControls.length; nInd++ )
+ GetPropSet( pControls[nInd] ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) );
+
+ if ( bEnable )
+ {
+ SetFocusTo( "WikiList" );
+ switchSendButtonIfNecessary();
+ }
+ else
+ {
+ GetPropSet( "SendButton" ).setPropertyValue( "Enabled", Boolean.valueOf( bEnable ) );
+ SetFocusTo( "CancelButton" );
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean callHandlerMethod( XDialog xDialog, Object EventObject, String MethodName )
+ {
+ if ( MethodName.equals( sSendMethod ) )
+ {
+ try
+ {
+ XPropertySet aWikiListProps = GetPropSet( "WikiList" );
+ XPropertySet aArticleTextProps = GetPropSet( "ArticleText" );
+ XPropertySet aCommentTextProps = GetPropSet( "CommentText" );
+ XPropertySet aMinorCheckProps = GetPropSet( "MinorCheck" );
+ XPropertySet aBrowserCheckProps = GetPropSet( "BrowserCheck" );
+
+ short [] sel = (short[]) aWikiListProps.getPropertyValue("SelectedItems");
+ String [] items = (String []) aWikiListProps.getPropertyValue("StringItemList");
+ m_sWikiEngineURL = items[sel[0]];
+ m_sWikiTitle = (String) aArticleTextProps.getPropertyValue("Text");
+ m_sWikiComment = (String) aCommentTextProps.getPropertyValue("Text");
+
+ short minorState = ((Short) aMinorCheckProps.getPropertyValue("State")).shortValue();
+ if (minorState != 0)
+ m_bWikiMinorEdit = true;
+ else
+ m_bWikiMinorEdit = false;
+
+ short nBrowserState = ((Short) aBrowserCheckProps.getPropertyValue("State")).shortValue();
+ Helper.SetShowInBrowserByDefault( m_xContext, nBrowserState != 0 );
+
+ // allow to disable other buttons
+ EnableControls( false );
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ final XDialog xDialogToClose = xDialog;
+ final XComponentContext xContext = m_xContext;
+
+ // start spinning
+ SetThrobberVisible( true );
+ SetThrobberActive( true );
+
+ // the following method might show a dialog, should be used in main thread
+ final Map<String,String> aWikiSettings = m_aSettings.getSettingByUrl( m_sWikiEngineURL );
+ if ( Helper.AllowThreadUsage( m_xContext ) )
+ {
+ m_aThread = new Thread( "com.sun.star.thread.WikiEditorSendingThread" )
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ if ( m_aWikiEditor != null )
+ {
+ Thread.yield();
+ m_bAction = m_aWikiEditor.SendArticleImpl(
+ WikiPropDialog.this, aWikiSettings);
+ }
+ }
+ finally
+ {
+ EnableControls( true );
+ SetThrobberActive( false );
+ SetThrobberVisible( false );
+
+ ThreadStop( true );
+ if ( m_bAction )
+ MainThreadDialogExecutor.Close( xContext, xDialogToClose );
+ }
+ }
+ };
+
+ m_aThread.start();
+ }
+ else
+ {
+ try
+ {
+ if (m_aWikiEditor != null && aWikiSettings != null)
+ {
+ m_bAction = m_aWikiEditor.SendArticleImpl(
+ WikiPropDialog.this, aWikiSettings);
+ }
+ } catch( java.lang.Exception e )
+ {}
+ finally
+ {
+ EnableControls( true );
+ SetThrobberActive( false );
+ SetThrobberVisible( false );
+
+ if ( m_bAction )
+ xDialogToClose.endExecute();
+ }
+ }
+
+ return true;
+ }
+ else if ( MethodName.equals( sWikiListMethod ) )
+ {
+ fillDocList();
+ switchSendButtonIfNecessary();
+ return true;
+ }
+ else if ( MethodName.equals( sArticleTextMethod ) )
+ {
+ switchSendButtonIfNecessary();
+ return true;
+ }
+ else if ( MethodName.equals( sAddWikiMethod ) )
+ {
+ WikiEditSettingDialog xAddDialog = new WikiEditSettingDialog(m_xContext, "vnd.sun.star.script:WikiEditor.EditSetting?location=application");
+ if ( xAddDialog.show() )
+ fillWikiList();
+
+ xAddDialog.DisposeDialog();
+
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void windowClosed( EventObject e )
+ {
+ ThreadStop( false );
+ }
+}
+
diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java b/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java
new file mode 100644
index 0000000000..7ca94390dc
--- /dev/null
+++ b/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java
@@ -0,0 +1,333 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.wiki;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.KeyStore;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+class WikiProtocolSocketFactory extends SSLSocketFactory
+{
+ private SSLContext m_aSSLContext;
+
+ private synchronized SSLContext GetNotSoSecureSSLContext()
+ {
+ if ( m_aSSLContext != null ) {
+ return m_aSSLContext;
+ }
+ TrustManager[] pTrustUnknownCerts = new TrustManager[]
+ {
+ new X509TrustManager() {
+ private X509TrustManager m_aOrgTrustManager;
+
+ private X509TrustManager GetOrgTrustManager()
+ {
+ if ( m_aOrgTrustManager == null )
+ {
+ try
+ {
+ TrustManagerFactory aFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() );
+ aFactory.init( (KeyStore)null );
+ TrustManager[] pTrustmanagers = aFactory.getTrustManagers();
+ if ( pTrustmanagers.length != 0 && pTrustmanagers[0] != null )
+ m_aOrgTrustManager = (X509TrustManager)pTrustmanagers[0];
+ }
+ catch( Exception e )
+ {
+ throw new RuntimeException( "No access to the default trust manager!", e );
+ }
+ }
+
+ if (m_aOrgTrustManager == null)
+ throw new RuntimeException("No access to the default trust manager!");
+
+ return m_aOrgTrustManager;
+ }
+
+ public X509Certificate[] getAcceptedIssuers()
+ {
+ return GetOrgTrustManager().getAcceptedIssuers();
+ }
+
+ public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException
+ {
+ GetOrgTrustManager().checkClientTrusted( certs, authType );
+ }
+
+ public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException
+ {
+ if ( certs == null || certs.length == 0 )
+ GetOrgTrustManager().checkServerTrusted( certs, authType );
+ else
+ for ( int nInd = 0; nInd < certs.length; nInd++ )
+ certs[nInd].checkValidity();
+ }
+ }
+ };
+
+ try
+ {
+ SSLContext aContext = SSLContext.getInstance("TLSv1.2");
+ if ( aContext != null )
+ {
+ aContext.init( null, pTrustUnknownCerts, null );
+ m_aSSLContext = aContext;
+ }
+ }
+ catch ( Exception e )
+ {
+ }
+
+ if ( m_aSSLContext == null )
+ throw new RuntimeException("failed to create SSLContext");
+
+ return m_aSSLContext;
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port)
+ throws IOException
+ {
+ return GetNotSoSecureSSLContext().getSocketFactory().createSocket(address, port);
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
+ throws IOException
+ {
+ return GetNotSoSecureSSLContext().getSocketFactory().createSocket(address, port, localAddress, localPort);
+ }
+
+ @Override
+ public Socket createSocket( String sHost, int nPort, InetAddress clientHost, int clientPort )
+ throws IOException, UnknownHostException
+ {
+ return GetNotSoSecureSSLContext().getSocketFactory().createSocket( sHost, nPort, clientHost, clientPort );
+ }
+
+ @Override
+ public Socket createSocket( String sHost, int nPort )
+ throws IOException, UnknownHostException
+ {
+ return GetNotSoSecureSSLContext().getSocketFactory().createSocket( sHost, nPort );
+ }
+
+ @Override
+ public Socket createSocket( Socket aSocket, String sHost, int nPort, boolean bAutoClose )
+ throws IOException
+ {
+ return GetNotSoSecureSSLContext().getSocketFactory().createSocket( aSocket, sHost, nPort, bAutoClose );
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites()
+ {
+ return GetNotSoSecureSSLContext().getSocketFactory().getDefaultCipherSuites();
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites()
+ {
+ return GetNotSoSecureSSLContext().getSocketFactory().getSupportedCipherSuites();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ return (obj != null) && (obj instanceof WikiProtocolSocketFactory);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return WikiProtocolSocketFactory.class.hashCode();
+ }
+}
+
+// A factory that creates streams that log everything that's written
+// to stderr - useful for debugging encrypted TLS connections
+class LoggingProtocolSocketFactory extends SSLSocketFactory
+{
+ private static class LogSocket extends SSLSocket
+ {
+ private final SSLSocket m_Socket;
+
+ public LogSocket(SSLSocket socket)
+ {
+ m_Socket = socket;
+ }
+
+ private static class LogStream extends java.io.FilterOutputStream
+ {
+ public LogStream(java.io.OutputStream stream)
+ {
+ super(stream);
+ }
+
+ @Override
+ public void write(byte[] buf, int offset, int len)
+ throws IOException
+ {
+ System.err.println("LogStream.write: \"" + new String(buf, offset, len, "UTF-8") + "\"");
+ out.write(buf, offset, len);
+ }
+ }
+
+ @Override
+ public java.io.OutputStream getOutputStream() throws IOException
+ {
+ return new LogStream(m_Socket.getOutputStream());
+ }
+
+ @Override public void addHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener listener) { m_Socket.addHandshakeCompletedListener(listener); }
+ @Override public String[] getEnabledCipherSuites() { return m_Socket.getEnabledCipherSuites(); }
+ @Override public String[] getEnabledProtocols() { return m_Socket.getEnabledProtocols(); }
+ @Override public boolean getEnableSessionCreation() { return m_Socket.getEnableSessionCreation(); }
+ @Override public boolean getNeedClientAuth() { return m_Socket.getNeedClientAuth(); }
+ @Override public javax.net.ssl.SSLSession getSession() { return m_Socket.getSession(); }
+ @Override public javax.net.ssl.SSLParameters getSSLParameters() { return m_Socket.getSSLParameters(); }
+ @Override public String[] getSupportedCipherSuites() { return m_Socket.getSupportedCipherSuites(); }
+ @Override public String[] getSupportedProtocols() { return m_Socket.getSupportedProtocols(); }
+ @Override public boolean getUseClientMode() { return m_Socket.getUseClientMode(); }
+ @Override public boolean getWantClientAuth() { return m_Socket.getWantClientAuth(); }
+ @Override public void removeHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener listener) { m_Socket.removeHandshakeCompletedListener(listener); }
+ @Override public void setEnabledCipherSuites(String[] suites) { m_Socket.setEnabledCipherSuites(suites); }
+ @Override public void setEnabledProtocols(String[] protocols) { m_Socket.setEnabledProtocols(protocols); }
+ @Override public void setEnableSessionCreation(boolean flag) { m_Socket.setEnableSessionCreation(flag); }
+ @Override public void setNeedClientAuth(boolean need) { m_Socket.setNeedClientAuth(need); }
+ @Override public void setSSLParameters(javax.net.ssl.SSLParameters params) { m_Socket.setSSLParameters(params); }
+ @Override public void setUseClientMode(boolean mode) { m_Socket.setUseClientMode(mode); }
+ @Override public void setWantClientAuth(boolean want) { m_Socket.setWantClientAuth(want); }
+ @Override public void startHandshake() throws IOException { m_Socket.startHandshake(); }
+
+ @Override public void bind(java.net.SocketAddress bindpoint) throws IOException { m_Socket.bind(bindpoint); }
+ @Override public void close() throws IOException { m_Socket.close(); }
+ @Override public void connect(java.net.SocketAddress endpoint) throws IOException { m_Socket.connect(endpoint); }
+ @Override public void connect(java.net.SocketAddress endpoint, int timeout) throws IOException { m_Socket.connect(endpoint, timeout); }
+ @Override public java.nio.channels.SocketChannel getChannel() { return m_Socket.getChannel(); }
+ @Override public InetAddress getInetAddress() { return m_Socket.getInetAddress(); }
+ @Override public java.io.InputStream getInputStream() throws IOException { return m_Socket.getInputStream(); }
+ @Override public boolean getKeepAlive() throws java.net.SocketException { return m_Socket.getKeepAlive(); }
+ @Override public InetAddress getLocalAddress() { return m_Socket.getLocalAddress(); }
+ @Override public int getLocalPort() { return m_Socket.getLocalPort(); }
+ @Override public java.net.SocketAddress getLocalSocketAddress() { return m_Socket.getLocalSocketAddress(); }
+ @Override public boolean getOOBInline() throws java.net.SocketException { return m_Socket.getOOBInline(); }
+ @Override public int getPort() { return m_Socket.getPort(); }
+ @Override public int getReceiveBufferSize() throws java.net.SocketException { return m_Socket.getReceiveBufferSize(); }
+ @Override public java.net.SocketAddress getRemoteSocketAddress() { return m_Socket.getRemoteSocketAddress(); }
+ @Override public boolean getReuseAddress() throws java.net.SocketException { return m_Socket.getReuseAddress(); }
+ @Override public int getSendBufferSize() throws java.net.SocketException { return m_Socket.getSendBufferSize(); }
+ @Override public int getSoLinger() throws java.net.SocketException { return m_Socket.getSoLinger(); }
+ @Override public int getSoTimeout() throws java.net.SocketException { return m_Socket.getSoTimeout(); }
+ @Override public boolean getTcpNoDelay() throws java.net.SocketException { return m_Socket.getTcpNoDelay(); }
+ @Override public int getTrafficClass() throws java.net.SocketException { return m_Socket.getTrafficClass(); }
+ @Override public boolean isBound() { return m_Socket.isBound(); }
+ @Override public boolean isClosed() { return m_Socket.isClosed(); }
+ @Override public boolean isConnected() { return m_Socket.isConnected(); }
+ @Override public boolean isInputShutdown() { return m_Socket.isInputShutdown(); }
+ @Override public boolean isOutputShutdown() { return m_Socket.isOutputShutdown(); }
+ @Override public void sendUrgentData(int data) throws IOException { m_Socket.sendUrgentData(data); }
+ @Override public void setKeepAlive(boolean on) throws java.net.SocketException { m_Socket.setKeepAlive(on); }
+ @Override public void setOOBInline(boolean on) throws java.net.SocketException { m_Socket.setOOBInline(on); }
+ @Override public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { m_Socket.setPerformancePreferences(connectionTime, latency, bandwidth); }
+ @Override public void setReceiveBufferSize(int size) throws java.net.SocketException { m_Socket.setReceiveBufferSize(size); }
+ @Override public void setReuseAddress(boolean on) throws java.net.SocketException { m_Socket.setReuseAddress(on); }
+ @Override public void setSendBufferSize(int size) throws java.net.SocketException { m_Socket.setSendBufferSize(size); }
+ @Override public void setSoLinger(boolean on, int linger) throws java.net.SocketException { m_Socket.setSoLinger(on, linger); }
+ @Override public void setSoTimeout(int timeout) throws java.net.SocketException{ m_Socket.setSoTimeout(timeout); }
+ @Override public void setTcpNoDelay(boolean on) throws java.net.SocketException{ m_Socket.setTcpNoDelay(on); }
+ @Override public void setTrafficClass(int tc) throws java.net.SocketException { m_Socket.setTrafficClass(tc); }
+ @Override public void shutdownInput() throws IOException { m_Socket.shutdownInput(); }
+ @Override public void shutdownOutput() throws IOException { m_Socket.shutdownOutput(); }
+ @Override public String toString() { return m_Socket.toString(); }
+
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port)
+ throws IOException
+ {
+ return new LogSocket((SSLSocket) SSLSocketFactory.getDefault().createSocket(address, port));
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
+ throws IOException
+ {
+ return new LogSocket((SSLSocket) SSLSocketFactory.getDefault().createSocket(address, port, localAddress, localPort));
+ }
+
+ @Override
+ public Socket createSocket( String sHost, int nPort, InetAddress clientHost, int clientPort )
+ throws IOException, UnknownHostException
+ {
+ return new LogSocket((SSLSocket) SSLSocketFactory.getDefault().createSocket(sHost, nPort, clientHost, clientPort));
+ }
+
+ @Override
+ public Socket createSocket( String sHost, int nPort )
+ throws IOException, UnknownHostException
+ {
+ return new LogSocket((SSLSocket) SSLSocketFactory.getDefault().createSocket(sHost, nPort));
+ }
+
+ @Override
+ public Socket createSocket( Socket aSocket, String sHost, int nPort, boolean bAutoClose )
+ throws IOException
+ {
+ return new LogSocket((SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(aSocket, sHost, nPort, bAutoClose));
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites()
+ {
+ // have to implement abstract method, just use the default
+ return ((SSLSocketFactory) SSLSocketFactory.getDefault()).getDefaultCipherSuites();
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites()
+ {
+ // have to implement abstract method, just use the default
+ return ((SSLSocketFactory) SSLSocketFactory.getDefault()).getSupportedCipherSuites();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ return (obj != null) && (obj instanceof LoggingProtocolSocketFactory);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return LoggingProtocolSocketFactory.class.hashCode();
+ }
+}
+
diff --git a/swext/mediawiki/src/components.rdb b/swext/mediawiki/src/components.rdb
new file mode 100644
index 0000000000..7cee92900d
--- /dev/null
+++ b/swext/mediawiki/src/components.rdb
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+-->
+<components xmlns="http://openoffice.org/2010/uno-components">
+ <component loader="com.sun.star.loader.Java2" uri="./mediawiki.jar">
+ <implementation name="com.sun.star.wiki.WikiOptionsEventHandlerImpl">
+ <service name="com.sun.star.wiki.WikiOptionsEventHandler"/>
+ </implementation>
+ <implementation name="com.sun.star.wiki.WikiEditorImpl">
+ <service name="com.sun.star.wiki.WikiEditor"/>
+ </implementation>
+ </component>
+</components>
diff --git a/swext/mediawiki/src/description-en-US.txt b/swext/mediawiki/src/description-en-US.txt
new file mode 100644
index 0000000000..d993ce1056
--- /dev/null
+++ b/swext/mediawiki/src/description-en-US.txt
@@ -0,0 +1 @@
+The Wiki Publisher enables you to create Wiki articles on MediaWiki servers without having to know the syntax of the MediaWiki markup language. Publish your new and existing documents transparently with the Writer to a wiki page.
diff --git a/swext/mediawiki/src/description.xml b/swext/mediawiki/src/description.xml
new file mode 100644
index 0000000000..e83d4f3085
--- /dev/null
+++ b/swext/mediawiki/src/description.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+-->
+<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:d="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <version value="1.2.0"/>
+ <identifier value="com.sun.wiki-publisher"/>
+ <display-name>
+ <name lang="en-US">Wiki Publisher</name>
+ </display-name>
+ <dependencies>
+ <OpenOffice.org-minimal-version value="3.0" d:name="OpenOffice.org 3.0 or StarOffice 9"/>
+ </dependencies>
+ <publisher>
+ <name xlink:href="http://www.documentfoundation.org" lang="en-US">The Document Foundation</name>
+ </publisher>
+ <extension-description>
+ <src xlink:href="description-en-US.txt" lang="en-US"/>
+ </extension-description>
+</description>
diff --git a/swext/mediawiki/src/filter/mediawiki.ott b/swext/mediawiki/src/filter/mediawiki.ott
new file mode 100644
index 0000000000..eb94e9607b
--- /dev/null
+++ b/swext/mediawiki/src/filter/mediawiki.ott
Binary files differ
diff --git a/swext/mediawiki/src/filter/odt2mediawiki.xsl b/swext/mediawiki/src/filter/odt2mediawiki.xsl
new file mode 100644
index 0000000000..435f0f498c
--- /dev/null
+++ b/swext/mediawiki/src/filter/odt2mediawiki.xsl
@@ -0,0 +1,2012 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ odt2mediawiki: OpenDocument to WikiMedia transformation
+ Copyright (C) 2007-2013 Bernhard Haumacher (haui at haumacher dot de)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ $Id: odt2mediawiki.xsl 3180 2013-03-17 16:00:43Z hauma $
+-->
+<stylesheet version="1.0"
+ xmlns="http://www.w3.org/1999/XSL/Transform"
+
+ xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
+ xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
+ xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
+ xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
+ xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
+ xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
+ xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
+ xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
+ xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
+ xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
+ xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
+ xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
+ xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:math="http://www.w3.org/1998/Math/MathML"
+ xmlns:dom="http://www.w3.org/2001/xml-events"
+ xmlns:xforms="http://www.w3.org/2002/xforms"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+>
+
+ <!--
+ == Customization options ==
+ -->
+
+ <!-- Constant defining the newline token. -->
+ <param name="NL" select="'&#10;'"/>
+
+ <!-- String that a tabulator is expanded with in preformatted paragraphs. -->
+
+ <variable name="codetabdocument-value"
+ select="/office:document/office:meta/meta:user-defined[@meta:name='CODE_TAB_REPLACEMENT']"/>
+
+ <param name="CODE_TAB_REPLACEMENT">
+
+ <choose>
+
+ <when test="boolean($codetabdocument-value)">
+ <value-of select="$codetabdocument-value"/>
+ </when>
+
+ <otherwise>
+ <value-of select="' '"/>
+ </otherwise>
+ </choose>
+ </param>
+
+ <!--
+ Switch that suppresses separation of paragraphs with empty lines.
+ (Set to 1 to activate) -->
+ <param name="CODE_JOIN_PARAGRAPHS"
+ select="boolean(string(/office:document/office:meta/meta:user-defined[@meta:name='CODE_JOIN_PARAGRAPHS']) != 'false')"/>
+
+ <variable name="document-value"
+ select="/office:document/office:meta/meta:user-defined[@meta:name='CODE_STYLES']"/>
+
+ <param name="CODE_STYLES">
+
+ <choose>
+ <when test="boolean($document-value)">
+ <value-of select="$document-value"/>
+ </when>
+
+ <otherwise>
+ <value-of select="''"/>
+ </otherwise>
+ </choose>
+ </param>
+
+ <variable name="table-class"
+ select="/office:document/office:meta/meta:user-defined[@meta:name='TABLE_CLASS']"/>
+
+ <param name="TABLE_CLASS">
+ <choose>
+ <when test="boolean($table-class)">
+ <value-of select="$table-class"/>
+ </when>
+
+ <otherwise>
+ <value-of select="''"/>
+ </otherwise>
+ </choose>
+ </param>
+
+ <variable name="USE_DEFAULT_TABLE_CLASS" select="string-length($TABLE_CLASS) &gt; 0"/>
+
+
+ <!--
+ == Wiki style constants ==
+ -->
+
+ <!-- Bold character style. -->
+ <variable name="BOLD_BIT" select="1"/>
+
+ <!-- Italic character style. -->
+ <variable name="ITALIC_BIT" select="2"/>
+
+ <!-- Underline character style. -->
+ <variable name="UNDERLINE_BIT" select="4"/>
+
+ <!-- Subscript character style. -->
+ <variable name="SUBSCRIPT_BIT" select="8"/>
+
+ <!-- Superscript character style. -->
+ <variable name="SUPERSCRIPT_BIT" select="16"/>
+
+ <!-- Typewriter character style. -->
+ <variable name="TYPEWRITER_BIT" select="32"/>
+
+ <!-- Preformatted text paragraph style. -->
+ <variable name="CODE_BIT" select="64"/>
+
+ <!-- Centered paragraph style. -->
+ <variable name="CENTER_BIT" select="128"/>
+
+ <!-- Right aligned paragraph style. -->
+ <variable name="RIGHT_BIT" select="256"/>
+
+ <!-- Constant defining the empty style. -->
+ <variable name="NO_STYLE" select="0"/>
+
+
+
+ <output
+ method="text"
+ media-type="text/plain"
+ encoding="UTF-8"
+ />
+
+
+ <!--
+ == Reference resolution ==
+ -->
+
+ <key
+ name="style-ref"
+ match="//style:style"
+ use="@style:name"
+ />
+
+ <key
+ name="list-style-ref"
+ match="//text:list-style"
+ use="@style:name"
+ />
+
+ <key
+ name="font-face-ref"
+ match="//style:font-face"
+ use="@style:name"
+ />
+
+ <key
+ name="text:table-of-content-entry-ref"
+ match="//text:table-of-content-entry-template"
+ use="@text:style-name"
+ />
+
+ <key
+ name="reference-resolution"
+ match="//text:reference-mark | //text:reference-mark-start"
+ use="@text:name"
+ />
+
+
+ <!--
+ Multiple pages (draw only)
+ -->
+
+ <template match="draw:page">
+ <value-of select="concat('&#10;&lt;!-- Page ', @draw:name, '--&gt;&#10;')"/>
+ <apply-templates/>
+ <value-of select="'&#10;----&#10;&#10;'"/>
+ </template>
+
+
+ <!--
+ == Lists ==
+ -->
+
+ <template match="text:list">
+ <!--
+ Check, whether this list is used to implement the outline numbering
+ for headings. Such list must not be exported, because within the wiki,
+ automatic outline numbering is performed. An outline list has a single
+ text:h element as its single leaf grandchild.
+
+ This method of section numbering seems not to be used when creating new
+ documents with OpenOffice.org 2.2, but the document containing the
+ OpenDocument specification version 1.1 uses such numbering through nested
+ lists.
+ -->
+ <choose>
+ <when test="boolean(./descendant::node()[not(./self::text:list) and not(./self::text:list-item) and not(./ancestor-or-self::text:h)])">
+ <apply-templates/>
+ </when>
+
+ <otherwise>
+ <apply-templates select=".//text:h"/>
+ </otherwise>
+ </choose>
+ </template>
+
+ <template match="text:list-item">
+ <if test="position() &gt; 1 or boolean(ancestor::text:list-item)">
+ <value-of select="$NL"/>
+ </if>
+ <variable name="list-style"
+ select="key('list-style-ref',ancestor::text:list[boolean(@text:style-name)][1]/@text:style-name)"/>
+ <call-template name="mk-list-token">
+ <with-param name="list-style" select="$list-style"/>
+ <with-param name="level" select="count(ancestor::text:list)"/>
+ </call-template>
+ <text> </text>
+ <apply-templates/>
+ <if test="position() = last() and not(boolean(ancestor::text:list-item))">
+ <!-- End of (potentially nested) list is marked with a double newline. -->
+ <value-of select="$NL"/>
+ <value-of select="$NL"/>
+ </if>
+ </template>
+
+ <template name="mk-list-token">
+ <param name="list-style"/>
+ <param name="level"/>
+
+ <if test="$level &gt; 1">
+ <call-template name="mk-list-token">
+ <with-param name="list-style" select="$list-style"/>
+ <with-param name="level" select="$level - 1"/>
+ </call-template>
+ </if>
+
+ <variable name="number-style" select="$list-style/text:list-level-style-number[@text:level=$level]"/>
+ <variable name="bullet-style" select="$list-style/text:list-level-style-bullet[@text:level=$level]"/>
+ <choose>
+ <when test="boolean($number-style)">
+ <choose>
+ <when test="string-length($number-style/@style:num-format) &gt; 0">
+ <text>#</text>
+ </when>
+ <otherwise>
+ <text>:</text>
+ </otherwise>
+ </choose>
+ </when>
+ <when test="boolean($bullet-style)">
+ <text>*</text>
+ </when>
+ </choose>
+ </template>
+
+
+ <!--
+ == Headings ==
+ -->
+
+ <template match="text:h">
+ <if test="string-length(.) &gt; 0">
+ <variable name="token">
+ <call-template name="mk-heading-prefix">
+ <with-param name="level" select="@text:outline-level"/>
+ </call-template>
+ </variable>
+ <value-of select="$token"/>
+ <text> </text>
+ <apply-templates/>
+ <text> </text>
+ <value-of select="$token"/>
+ <value-of select="$NL"/>
+ <value-of select="$NL"/>
+ </if>
+ </template>
+
+ <template match="text:index-title">
+ <text>__NOTOC__</text>
+ <value-of select="$NL"/>
+ <text>== </text>
+ <apply-templates/>
+ <text> ==</text>
+ <value-of select="$NL"/>
+ <value-of select="$NL"/>
+ </template>
+
+ <!--
+ Function generating a wiki heading prefix.
+
+ @param level
+ The heading level. The value must be between 1 and 6.
+ -->
+ <template name="mk-heading-prefix">
+ <param name="level"/>
+ <choose>
+ <when test="$level &gt; 6">
+ <call-template name="mk-heading-prefix">
+ <with-param name="level" select="6"/>
+ </call-template>
+ </when>
+ <when test="$level &gt; 0">
+ <text>=</text>
+ <call-template name="mk-heading-prefix">
+ <with-param name="level" select="$level - 1"/>
+ </call-template>
+ </when>
+ </choose>
+ </template>
+
+ <!--
+ Function generating a token consisting of the given character
+ repeated 'level' times.
+
+ @param level
+ The length of the result.
+ @param char
+ The character that should be repeated 'level' times.
+ -->
+ <template name="mk-token">
+ <param name="level"/>
+ <param name="char"/>
+ <if test="$level &gt; 0">
+ <value-of select="$char"/>
+ <call-template name="mk-token">
+ <with-param name="level" select="$level - 1"/>
+ <with-param name="char" select="$char"/>
+ </call-template>
+ </if>
+ </template>
+
+
+ <!--
+ == Tables ==
+ -->
+
+ <template match="table:table">
+ <value-of select="$NL"/>
+ <text>{|</text>
+
+ <choose>
+ <when test="$USE_DEFAULT_TABLE_CLASS">
+ <text> class="</text>
+ <value-of select="$TABLE_CLASS"/>
+ <text>"</text>
+ </when>
+
+ <otherwise>
+ <variable name="style-element" select="key('style-ref', @table:style-name)"/>
+ <variable name="table-align" select="$style-element/style:table-properties/@table:align"/>
+ <!-- Table alignment using align -->
+ <if test="boolean($table-align)">
+ <variable name="align">
+ <choose>
+ <when test="$table-align='center'">
+ <text>center</text>
+ </when>
+ </choose>
+ </variable>
+ <if test="string-length($align) &gt; 0">
+ <text> align="</text>
+ <value-of select="$align"/>
+ <text>"</text>
+ </if>
+ </if>
+ <variable name="style">
+ <!-- Default setting to translate detailed office table cell styles correctly. -->
+ <text>border-spacing:0;</text>
+ <!-- Table alignment using css -->
+ <if test="boolean($table-align)">
+ <choose>
+ <when test="$table-align='margins'">
+ <text>margin:auto;</text>
+ </when>
+ </choose>
+ </if>
+ <if test="boolean($style-element/style:table-properties/@style:width)">
+ <text>width:</text>
+ <value-of select="$style-element/style:table-properties/@style:width"/>
+ <text>;</text>
+ </if>
+ </variable>
+ <text> style="</text>
+ <value-of select="$style"/>
+ <text>"</text>
+ </otherwise>
+ </choose>
+
+ <value-of select="$NL"/>
+ <apply-templates/>
+ <text>|-</text>
+ <value-of select="$NL"/>
+ <text>|}</text>
+ <value-of select="$NL"/>
+ </template>
+
+ <template match="table:table-header-rows">
+ <apply-templates/>
+ </template>
+
+ <template match="table:table-row">
+ <text>|-</text>
+
+ <if test="not($USE_DEFAULT_TABLE_CLASS) and boolean(table:table-cell[1]/@table:style-name)">
+ <variable name="style-name" select="table:table-cell[1]/@table:style-name"/>
+ <variable name="total-style-name" select="count(table:table-cell/@table:style-name)"/>
+ <variable name="total-equal-style-name" select="count(table:table-cell[@table:style-name=$style-name])"/>
+
+ <variable name="style">
+ <if test="$total-equal-style-name=$total-style-name">
+ <call-template name="translate-table-cell-properties">
+ <with-param name="style-element" select="key('style-ref', $style-name)"/>
+ </call-template>
+ </if>
+ </variable>
+
+ <if test="string-length($style) &gt; 0">
+ <text> style="</text>
+ <value-of select="$style"/>
+ <text>"</text>
+ </if>
+ </if>
+
+ <value-of select="$NL"/>
+ <apply-templates/>
+ </template>
+
+ <template match="table:table-header-rows//table:table-cell">
+ <text>!</text>
+ <if test="@table:number-columns-spanned">
+ <text>colspan="</text>
+ <value-of select="@table:number-columns-spanned"/>
+ <text>" | </text>
+ </if>
+
+ <!-- Cell alignment -->
+ <if test="text:p and count(*) = 1">
+ <variable name="style-number">
+ <call-template name="mk-style-set">
+ <with-param name="node" select="text:p"/>
+ </call-template>
+ </variable>
+
+ <variable name="code"
+ select="($style-number mod (2 * $CODE_BIT)) - ($style-number mod ($CODE_BIT)) != 0"/>
+ <variable name="center"
+ select="($style-number mod (2 * $CENTER_BIT)) - ($style-number mod ($CENTER_BIT)) != 0"/>
+ <variable name="right"
+ select="($style-number mod (2 * $RIGHT_BIT)) - ($style-number mod ($RIGHT_BIT)) != 0"/>
+
+ <choose>
+ <when test="$center">
+ <text> align=center</text>
+ </when>
+ <when test="$right">
+ <text> align=right</text>
+ </when>
+ </choose>
+ </if>
+
+ <if test="not($USE_DEFAULT_TABLE_CLASS) and boolean(@table:style-name)">
+ <variable name="style-name" select="@table:style-name"/>
+
+ <variable name="style">
+ <!-- Only if cells have a different style-name -->
+ <if test="count(../table:table-cell/@table:style-name) != count(../table:table-cell[@table:style-name=$style-name]) and count(../table:table-cell/@table:style-name) &gt; 0">
+ <call-template name="translate-table-cell-properties">
+ <with-param name="style-element" select="key('style-ref', $style-name)"/>
+ </call-template>
+ </if>
+ </variable>
+
+ <if test="string-length($style) &gt; 0">
+ <text> style="</text>
+ <value-of select="$style"/>
+ <text>" </text>
+ </if>
+ </if>
+ <text>| </text>
+ <apply-templates/>
+ <value-of select="$NL"/>
+ </template>
+
+ <template match="table:table-cell">
+ <text>|</text>
+ <if test="@table:number-columns-spanned">
+ <text> colspan="</text>
+ <value-of select="@table:number-columns-spanned"/>
+ <text>" </text>
+ </if>
+
+ <!-- Cell alignment -->
+ <if test="text:p and count(*) = 1">
+ <variable name="style-number">
+ <call-template name="mk-style-set">
+ <with-param name="node" select="text:p"/>
+ </call-template>
+ </variable>
+
+ <variable name="code"
+ select="($style-number mod (2 * $CODE_BIT)) - ($style-number mod ($CODE_BIT)) != 0"/>
+ <variable name="center"
+ select="($style-number mod (2 * $CENTER_BIT)) - ($style-number mod ($CENTER_BIT)) != 0"/>
+ <variable name="right"
+ select="($style-number mod (2 * $RIGHT_BIT)) - ($style-number mod ($RIGHT_BIT)) != 0"/>
+
+ <choose>
+ <when test="$center">
+ <text> align=center</text>
+ </when>
+ <when test="$right">
+ <text> align=right</text>
+ </when>
+ </choose>
+ </if>
+
+ <if test="not($USE_DEFAULT_TABLE_CLASS) and boolean(@table:style-name)">
+ <variable name="style-name" select="@table:style-name"/>
+
+ <variable name="style">
+ <!-- Only if cells have a different style-name -->
+ <if test="count(../table:table-cell/@table:style-name) != count(../table:table-cell[@table:style-name=$style-name]) and count(../table:table-cell/@table:style-name) &gt; 0">
+ <call-template name="translate-table-cell-properties">
+ <with-param name="style-element" select="key('style-ref', $style-name)"/>
+ </call-template>
+ </if>
+ <!-- Font color -->
+ <if test="text:p and count(*) = 1">
+ <if test="boolean(text:p/@text:style-name)">
+ <variable name="style-element" select="key('style-ref', text:p/@text:style-name)"/>
+
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'color'"/>
+ <with-param name="style-property" select="$style-element/style:text-properties/@fo:color"/>
+ </call-template>
+ </if>
+ </if>
+ </variable>
+
+ <if test="string-length($style) &gt; 0">
+ <text> style="</text>
+ <value-of select="$style"/>
+ <text>" </text>
+ </if>
+ </if>
+ <text>| </text>
+ <apply-templates/>
+ <value-of select="$NL"/>
+ </template>
+
+ <template name="translate-table-cell-properties">
+ <param name="style-element"/>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'background-color'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:background-color"/>
+ </call-template>
+
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'border'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:border"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'border-top'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:border-top"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'border-bottom'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:border-bottom"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'border-left'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:border-left"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'border-right'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:border-right"/>
+ </call-template>
+
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'padding'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:padding"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'padding-top'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:padding-top"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'padding-bottom'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:padding-bottom"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'padding-left'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:padding-left"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'padding-right'"/>
+ <with-param name="style-property" select="$style-element/style:table-cell-properties/@fo:padding-right"/>
+ </call-template>
+ </template>
+
+ <template name="translate-style-property">
+ <param name="style-name"/>
+ <param name="style-property"/>
+
+ <if test="boolean($style-property)">
+ <value-of select="$style-name"/>
+ <text>:</text>
+ <value-of select="string($style-property)"/>
+ <text>;</text>
+ </if>
+ </template>
+
+ <!--
+ == WikiMath ==
+ -->
+
+ <!--
+ Make sure to join sibling node that are all formatted with WikiMath style without repeating
+ the <math>..</math> markup.
+
+ Do not apply any transformation to the contents marked as WikiMath.
+ -->
+ <template match="text:span[@text:style-name='WikiMath']">
+ <value-of select="'&lt;math&gt;'"/>
+ <value-of select="string(.)"/>
+ <value-of select="'&lt;/math&gt;'"/>
+ </template>
+
+ <template match="text:span[@text:style-name='WikiMath' and boolean(preceding-sibling::node()[position()=1 and local-name(.)='span' and @text:style-name='WikiMath'])]">
+ <value-of select="string(.)"/>
+ <value-of select="'&lt;/math&gt;'"/>
+ </template>
+
+ <template match="text:span[@text:style-name='WikiMath' and boolean(following-sibling::node()[position()=1 and local-name(.)='span' and @text:style-name='WikiMath'])]">
+ <value-of select="'&lt;math&gt;'"/>
+ <value-of select="string(.)"/>
+ </template>
+
+ <template match="text:span[@text:style-name='WikiMath' and boolean(following-sibling::node()[position()=1 and local-name(.)='span' and @text:style-name='WikiMath']) and boolean(preceding-sibling::node()[position()=1 and local-name(.)='span' and @text:style-name='WikiMath'])]">
+ <value-of select="string(.)"/>
+ </template>
+
+ <!--
+ == Native links ==
+ -->
+
+ <template match="text:a">
+ <variable name="link-ref" select="@xlink:href"/>
+ <choose>
+ <when test="string-length($link-ref) &gt; 0">
+ <choose>
+ <when test="starts-with($link-ref, '#')">
+ <text>[[</text>
+ <choose>
+ <when test="contains($link-ref, '_')">
+ <value-of select="translate($link-ref,'_','')"/>
+ </when>
+ <otherwise>
+ <value-of select="$link-ref"/>
+ </otherwise>
+ </choose>
+ <text>|</text>
+ <choose>
+ <when test="text:tab and ancestor::text:index-body">
+ <value-of select="node()[1]"/>
+ </when>
+ <otherwise>
+ <value-of select="string(.)"/>
+ </otherwise>
+ </choose>
+ <text>]]</text>
+ </when>
+
+ <otherwise>
+ <text>[</text>
+ <value-of select="$link-ref"/>
+ <text> </text>
+ <value-of select="string(.)"/>
+ <text>]</text>
+ </otherwise>
+ </choose>
+ </when>
+
+ <otherwise>
+ <apply-templates/>
+ </otherwise>
+ </choose>
+ </template>
+
+ <!--
+ Function for generating tabulations in TOC entries.
+
+ @param style
+ The style of the TOC entry
+ -->
+ <template name="mk-tab-toc">
+ <param name="style"/>
+ <if test="number($style/@text:outline-level) &gt; 0">
+ <call-template name="mk-token">
+ <with-param name="level" select="number($style/@text:outline-level) - 1"/>
+ <with-param name="char" select="':'"/>
+ </call-template>
+ </if>
+ </template>
+
+ <!--
+ == WikiLink ==
+ -->
+
+ <template match="text:span[@text:style-name='WikiLink']">
+ <value-of select="'[['"/>
+ <variable name="link-def" select="string(.)"/>
+ <variable name="link-label" select="normalize-space(substring-before($link-def, '['))"/>
+ <variable name="link-ref" select="normalize-space(substring-before(substring-after($link-def, '['), ']'))"/>
+ <choose>
+ <when test="boolean($link-ref)">
+ <value-of select="concat($link-ref, '|', $link-label)"/>
+ </when>
+ <otherwise>
+ <value-of select="$link-def"/>
+ </otherwise>
+ </choose>
+ <value-of select="']]'"/>
+ </template>
+
+
+ <!--
+ == Paragraphs ==
+ -->
+
+ <template match="text:p">
+ <!-- TOC tabs -->
+ <if test="ancestor::text:index-body and boolean(@text:style-name)">
+ <variable name="style" select="key('style-ref', @text:style-name)"/>
+ <if test="boolean($style/@style:parent-style-name)">
+ <call-template name="mk-tab-toc">
+ <with-param name="style" select="key('text:table-of-content-entry-ref', $style/@style:parent-style-name)"/>
+ </call-template>
+ </if>
+ </if>
+
+ <variable name="alignment">
+ <call-template name="mk-style-set">
+ <with-param name="node" select="."/>
+ </call-template>
+ </variable>
+
+ <variable name="code"
+ select="($alignment mod (2 * $CODE_BIT)) - ($alignment mod ($CODE_BIT)) != 0"/>
+ <variable name="center"
+ select="($alignment mod (2 * $CENTER_BIT)) - ($alignment mod ($CENTER_BIT)) != 0"/>
+ <variable name="right"
+ select="($alignment mod (2 * $RIGHT_BIT)) - ($alignment mod ($RIGHT_BIT)) != 0"/>
+
+ <variable name="style">
+ <choose>
+ <when test="name(parent::*) != 'table:table-cell'">
+ <choose>
+ <when test="$center">
+ <text>text-align:center;</text>
+ </when>
+ <when test="$right">
+ <text>text-align:right;</text>
+ </when>
+ </choose>
+ <if test="boolean(@text:style-name)">
+ <variable name="style-element" select="key('style-ref', @text:style-name)"/>
+
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'color'"/>
+ <with-param name="style-property" select="$style-element/style:text-properties/@fo:color"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'margin-left'"/>
+ <with-param name="style-property" select="$style-element/style:paragraph-properties/@fo:margin-left"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'margin-right'"/>
+ <with-param name="style-property" select="$style-element/style:paragraph-properties/@fo:margin-right"/>
+ </call-template>
+ </if>
+ </when>
+ <otherwise>
+ <if test="count(../text:p) &gt; 1 and boolean(@text:style-name)">
+ <variable name="style-element" select="key('style-ref', @text:style-name)"/>
+
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'color'"/>
+ <with-param name="style-property" select="$style-element/style:text-properties/@fo:color"/>
+ </call-template>
+ </if>
+ </otherwise>
+ </choose>
+ </variable>
+
+ <if test="string-length($style) &gt; 0">
+ <text>&lt;div style="</text>
+ <value-of select="$style"/>
+ <text>"&gt;</text>
+ </if>
+
+ <apply-templates/>
+
+ <if test="string-length($style) &gt; 0">
+ <text>&lt;/div&gt;</text>
+ </if>
+
+ <variable name="paragraph-right"
+ select="./following-sibling::*[1]/self::text:p"/>
+
+ <choose>
+ <when test="boolean($paragraph-right)">
+ <!--
+ Insert end of line only if not within a list. Within wiki lists,
+ a line break leaves the current list item.
+ -->
+ <choose>
+ <when test="boolean(ancestor::text:list-item)">
+ <text>&lt;br/&gt;</text>
+ </when>
+ <when test="$code">
+ <variable name="style-right">
+ <call-template name="mk-style-set">
+ <with-param name="node" select="$paragraph-right"/>
+ </call-template>
+ </variable>
+
+ <variable name="code-right"
+ select="($style-right mod (2 * $CODE_BIT)) - ($style-right mod ($CODE_BIT)) != 0"/>
+
+ <choose>
+ <when test="$code-right">
+ <choose>
+ <when test="$CODE_JOIN_PARAGRAPHS">
+ <value-of select="$NL"/>
+ </when>
+
+ <otherwise>
+ <value-of select="$NL"/>
+ <value-of select="' '"/>
+ <value-of select="$NL"/>
+ </otherwise>
+ </choose>
+ </when>
+ <otherwise>
+ <value-of select="$NL"/>
+ <value-of select="$NL"/>
+ </otherwise>
+ </choose>
+ </when>
+ <otherwise>
+ <value-of select="$NL"/>
+ <value-of select="$NL"/>
+ </otherwise>
+ </choose>
+ </when>
+ <when test="not(boolean(ancestor::text:note)) and (boolean(./following::*[1]/self::text:h) or boolean(./following::*[1]/self::table:table) or boolean(./following::*[1]/self::text:bibliography))">
+ <!-- Newline before following heading or table. -->
+ <value-of select="$NL"/>
+ <value-of select="$NL"/>
+ </when>
+ <when test="not(./following-sibling::*[1]) and name(./following::*[1])='text:p' and ancestor::text:list-item">
+ <!-- End of the list -->
+ <value-of select="$NL"/>
+ <value-of select="$NL"/>
+ </when>
+ </choose>
+ </template>
+
+ <template match="text:p[string-length(.) = 0 and string-length(preceding-sibling::*[1]/self::text:p) &gt; 0]">
+ <value-of select="$NL"/>
+ </template>
+
+ <!--
+ == Preformatted text ==
+ -->
+
+ <template match="text:s">
+ <variable name="style">
+ <call-template name="mk-style-set">
+ <with-param name="node" select="."/>
+ </call-template>
+ </variable>
+
+ <variable name="code"
+ select="($style mod (2 * $CODE_BIT)) - ($style mod ($CODE_BIT)) != 0"/>
+
+ <if test="$code">
+ <choose>
+ <when test="@text:c">
+ <call-template name="mk-token">
+ <with-param name="level" select="@text:c"/>
+ <with-param name="char" select="' '"/>
+ </call-template>
+ </when>
+ <otherwise>
+ <value-of select="' '"/>
+ </otherwise>
+ </choose>
+ </if>
+ </template>
+
+ <template match="text:span[string-length(.) &gt; 0]">
+ <if test="boolean(@text:style-name)">
+ <variable name="style-element" select="key('style-ref', @text:style-name)"/>
+ <variable name="style">
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'background-color'"/>
+ <with-param name="style-property" select="$style-element/style:text-properties/@fo:background-color"/>
+ </call-template>
+ <call-template name="translate-style-property">
+ <with-param name="style-name" select="'color'"/>
+ <with-param name="style-property" select="$style-element/style:text-properties/@fo:color"/>
+ </call-template>
+ </variable>
+
+ <if test="string-length($style) &gt; 0">
+ <text>&lt;span style="</text>
+ <value-of select="$style"/>
+ <text>"&gt;</text>
+ </if>
+
+ <apply-templates/>
+
+ <if test="string-length($style) &gt; 0">
+ <text>&lt;/span&gt;</text>
+ </if>
+ </if>
+ </template>
+
+ <template match="text:tab">
+ <variable name="style">
+ <call-template name="mk-style-set">
+ <with-param name="node" select="."/>
+ </call-template>
+ </variable>
+
+ <variable name="code"
+ select="($style mod (2 * $CODE_BIT)) - ($style mod ($CODE_BIT)) != 0"/>
+
+ <if test="$code">
+ <value-of select="$CODE_TAB_REPLACEMENT"/>
+ </if>
+ </template>
+
+ <template match="text:line-break">
+ <variable name="style">
+ <call-template name="mk-style-set">
+ <with-param name="node" select="."/>
+ </call-template>
+ </variable>
+
+ <variable name="code"
+ select="($style mod (2 * $CODE_BIT)) - ($style mod ($CODE_BIT)) != 0"/>
+
+ <if test="$code">
+ <value-of select="$NL"/>
+ <value-of select="' '"/>
+ </if>
+ </template>
+
+ <!--
+ Footnotes
+ -->
+
+ <template match="text:note-body">
+ <variable name="note" select="./parent::text:note"/>
+
+ <if test="$note/@text:note-class = 'footnote'">
+ <text>&lt;ref name="</text>
+ <value-of select="$note/@text:id"/>
+ <text>"&gt;</text>
+ <apply-templates/>
+ <text>&lt;/ref&gt;</text>
+ </if>
+ </template>
+
+ <template match="text:note-ref[@text:note-class='footnote']">
+ <text>&lt;ref name="</text>
+ <value-of select="@text:ref-name"/>
+ <text>"/&gt;</text>
+ </template>
+
+
+ <!--
+ == Images ==
+ -->
+
+ <template match="draw:text-box[boolean(.//draw:image)]">
+ <variable name="image" select=".//draw:image[1]"/>
+
+ <variable name="image-description">
+ <apply-templates/>
+ </variable>
+
+ <variable name="picture">
+ <text>[[</text>
+ <call-template name="mk-image-name">
+ <with-param name="image" select="$image"/>
+ <with-param name="frame" select="."/>
+ <with-param name="extension" select="'.png'"/>
+ </call-template>
+ <text>|thumb</text>
+ </variable>
+
+ <!-- Picture markup + Horizontal & Vertical align -->
+ <call-template name="mk-image-align">
+ <with-param name="picture" select="$picture"/>
+ </call-template>
+
+ <!-- Image caption -->
+ <text>|</text>
+ <value-of select="normalize-space($image-description)"/>
+
+ <text>]]</text>
+ </template>
+
+ <template match="draw:image[not(boolean(ancestor::draw:text-box))]">
+ <variable name="picture">
+ <text>[[</text>
+ <call-template name="mk-image-name">
+ <with-param name="image" select="."/>
+ <with-param name="frame" select="parent::node()"/>
+ </call-template>
+ </variable>
+
+ <!-- Picture markup + Horizontal & Vertical align -->
+ <call-template name="mk-image-align">
+ <with-param name="picture" select="$picture"/>
+ </call-template>
+
+ <!-- Image alt -->
+ <if test="name(following-sibling::*)='svg:title'">
+ <text>|alt="</text>
+ <value-of select="following-sibling::*/text()"/>
+ <text>"</text>
+ </if>
+
+ <text>]]</text>
+ </template>
+
+ <template name="mk-image-align">
+ <param name="picture"/>
+
+ <choose>
+ <when test="name(..)='draw:frame' and boolean(../@draw:style-name)">
+ <variable name="style-element" select="key('style-ref', ../@draw:style-name)"/>
+ <choose>
+ <when test="boolean($style-element/style:graphic-properties/@style:wrap)">
+ <choose>
+ <!-- wrap=none -->
+ <when test="$style-element/style:graphic-properties/@style:wrap='none'">
+ <text>{{clear}}</text>
+ <value-of select="$NL"/>
+ <value-of select="$picture"/>
+ <choose>
+ <when test="boolean($style-element/style:graphic-properties/@style:horizontal-pos)">
+ <choose>
+ <when test="$style-element/style:graphic-properties/@style:horizontal-pos='center'">
+ <text>|center</text>
+ </when>
+ <otherwise>
+ <text>|none</text>
+ </otherwise>
+ </choose>
+ </when>
+ <otherwise>
+ <text>|none</text>
+ </otherwise>
+ </choose>
+ </when>
+ <!-- wrap != none -->
+ <otherwise>
+ <value-of select="$picture"/>
+ <!-- Horizontal align -->
+ <call-template name="mk-image-horizontal-align">
+ <with-param name="style-element" select="$style-element"/>
+ </call-template>
+ <!-- Vertical align -->
+ <call-template name="mk-image-vertical-align">
+ <with-param name="style-element" select="$style-element"/>
+ </call-template>
+ </otherwise>
+ </choose>
+ </when>
+ <!-- without wrap -->
+ <otherwise>
+ <value-of select="$picture"/>
+ <!-- Horizontal align -->
+ <call-template name="mk-image-horizontal-align">
+ <with-param name="style-element" select="$style-element"/>
+ </call-template>
+ <!-- Vertical align -->
+ <call-template name="mk-image-vertical-align">
+ <with-param name="style-element" select="$style-element"/>
+ </call-template>
+ </otherwise>
+ </choose>
+ </when>
+ <otherwise>
+ <value-of select="$picture"/>
+ </otherwise>
+ </choose>
+ </template>
+
+ <template name="mk-image-horizontal-align">
+ <param name="style-element"/>
+
+ <if test="boolean($style-element/style:graphic-properties/@style:horizontal-pos)">
+ <choose>
+ <when test="$style-element/style:graphic-properties/@style:horizontal-pos='right'">
+ <text>|right</text>
+ </when>
+ <when test="$style-element/style:graphic-properties/@style:horizontal-pos='left'">
+ <text>|left</text>
+ </when>
+ </choose>
+ </if>
+ </template>
+
+ <template name="mk-image-vertical-align">
+ <param name="style-element"/>
+
+ <if test="boolean($style-element/style:graphic-properties/@style:vertical-pos)">
+ <choose>
+ <when test="$style-element/style:graphic-properties/@style:vertical-pos='top'">
+ <text>|top</text>
+ </when>
+ <when test="$style-element/style:graphic-properties/@style:vertical-pos='middle'">
+ <text>|middle</text>
+ </when>
+ <when test="$style-element/style:graphic-properties/@style:vertical-pos='below'">
+ <text>|below</text>
+ </when>
+ </choose>
+ </if>
+ </template>
+
+ <template name="mk-image-name">
+ <param name="image"/>
+ <param name="frame"/>
+ <param name="extension"/>
+
+ <variable name="base-name">
+ <call-template name="mk-base-name">
+ <with-param name="href" select="$image/@xlink:href"/>
+ </call-template>
+ </variable>
+
+ <if test="not(starts-with($base-name, 'Image:'))">
+ <value-of select="'Image:'"/>
+ </if>
+ <value-of select="$base-name"/>
+ <value-of select="$frame/@draw:name"/>
+ <value-of select="'.png'"/>
+ </template>
+
+ <template name="mk-base-name">
+ <param name="href"/>
+
+ <variable name="result" select="substring-after($href, '/')"/>
+ <choose>
+ <when test="boolean($result)">
+ <call-template name="mk-base-name">
+ <with-param name="href" select="$result"/>
+ </call-template>
+ </when>
+ <otherwise>
+ <value-of select="$href"/>
+ </otherwise>
+ </choose>
+ </template>
+
+ <!-- Frames -->
+
+ <template match="draw:frame">
+ <choose>
+ <when test="draw:object/math:math">
+ <apply-templates select="draw:object/math:math[1]"/>
+ </when>
+
+ <when test="draw:image">
+ <apply-templates select="draw:image[1]"/>
+ </when>
+
+ <otherwise>
+ <apply-templates select="./*[1]"/>
+ </otherwise>
+ </choose>
+
+ </template>
+
+ <!-- Formulas (Objects) -->
+
+ <include href="math/mmltex.xsl"/>
+
+ <template match="math:math" priority="1">
+ <text>&lt;math&gt;</text>
+ <apply-templates/>
+ <text>&lt;/math&gt;</text>
+ </template>
+
+
+ <!--
+ References
+ -->
+
+ <!-- TODO: text:bibliography-mark -->
+
+ <template match="text:reference-ref">
+ <variable name="reference-mark" select="key('reference-resolution', @text:ref-name)"/>
+
+ <choose>
+ <when test="boolean($reference-mark)">
+ <!--
+ In wiki syntax, only a local reference to a heading can be inserted.
+ If the link target is a descendant of a heading element, a link can be
+ inserted in the result. -->
+ <variable name="header-anchor" select="$reference-mark/ancestor::text:h[1]"/>
+ <if test="boolean($header-anchor)">
+ <text>[[#</text>
+ <value-of select="string($header-anchor)"/>
+ <text>|</text>
+ </if>
+
+ <variable name="reference-text" select="string(.)"/>
+
+ <choose>
+ <!-- Check, whether the reference text is cached in the document. -->
+ <when test="string-length($reference-text) &gt; 0">
+ <value-of select="$reference-text"/>
+ </when>
+
+ <otherwise>
+ <!--
+ TODO: Evaluate the @text:reference-format attribute and
+ generate the replacement text (difficult).-->
+ <text>(REFERENCE TEXT UNAVAILABLE: "</text>
+ <value-of select="@text:ref-name"/>
+ <text>")</text>
+ </otherwise>
+ </choose>
+
+ <if test="boolean($header-anchor)">
+ <text>]]</text>
+ </if>
+ </when>
+
+ <otherwise>
+ <text>(UNDEFINED REFERENCE: "</text>
+ <value-of select="@text:ref-name"/>
+ <text>")</text>
+ </otherwise>
+ </choose>
+ </template>
+
+ <template match="text:reference-mark">
+ <!-- TODO: Output an anchor. -->
+ <apply-templates/>
+ </template>
+
+ <template match="text:reference-mark-start">
+ <!-- TODO: Output an anchor. -->
+ </template>
+
+ <template match="text:bookmark-start">
+ <if test="boolean(@text:name)">
+ <variable name="bookmark">
+ <choose>
+ <when test="contains(@text:name,'_')">
+ <value-of select="translate(@text:name,'_','')"/>
+ </when>
+ <otherwise>
+ <value-of select="@text:name"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <text>{{anchor|</text>
+ <value-of select="$bookmark"/>
+ <text>}} </text>
+ </if>
+ <apply-templates/>
+ </template>
+
+ <!--
+ == Plain text ==
+ -->
+
+ <template match="text:p/text() | text:h/text() | text:span/text() | text:sequence/text() | text:sequence-ref/text() | text:a/text() | text:bookmark-ref/text() | text:reference-mark/text() | text:date/text() | text:time/text() | text:page-number/text() | text:sender-firstname/text() | text:sender-lastname/text() | text:sender-initials/text() | text:sender-title/text() | text:sender-position/text() | text:sender-email/text() | text:sender-phone-private/text() | text:sender-fax/text() | text:sender-company/text() | text:sender-phone-work/text() | text:sender-street/text() | text:sender-city/text() | text:sender-postal-code/text() | text:sender-country/text() | text:sender-state-or-province/text() | text:author-name/text() | text:author-initials/text() | text:chapter/text() | text:file-name/text() | text:template-name/text() | text:sheet-name/text() | text:variable-get/text() | text:variable-input/text() | text:user-field-get/text() | text:user-field-input/text() | text:expression/text() | text:text-input/text() | text:initial-creator/text() | text:creation-date/text() | text:creation-time/text() | text:description/text() | text:user-defined/text() | text:print-date/text() | text:printed-by/text() | text:title/text() | text:subject/text() | text:keywords/text() | text:editing-cycles/text() | text:editing-duration/text() | text:modification-date/text() | text:creator/text() | text:modification-time/text() | text:page-count/text() | text:paragraph-count/text() | text:word-count/text() | text:character-count/text() | text:table-count/text() | text:image-count/text() | text:object-count/text() | text:database-display/text() | text:database-row-number/text() | text:database-name/text() | text:page-variable-get/text() | text:placeholder/text() | text:conditional-text/text() | text:hidden-text/text() | text:execute-macro/text() | text:dde-connection/text() | text:measure/text() | text:table-formula/text()">
+ <choose>
+ <when test="boolean(./ancestor::table:table-header-rows) or boolean(./ancestor::text:h)">
+ <!--
+ No explicit styles within table headings or section headings,
+ because those styles are consistently declared by the Wiki engine. -->
+ <value-of select="."/>
+ </when>
+
+ <when test="string-length(.) &gt; 0">
+ <variable name="style">
+ <call-template name="mk-style-set">
+ <with-param name="node" select="./parent::node()"/>
+ </call-template>
+ </variable>
+
+ <variable name="current-paragraph"
+ select="./ancestor::text:p[1]"/>
+ <variable name="paragraph-id"
+ select="generate-id($current-paragraph)"/>
+ <variable name="frames"
+ select="$current-paragraph/descendant::draw:frame"/>
+ <variable name="frame-count"
+ select="count($frames)"/>
+
+ <!--
+ The current style context consists of all text nodes that are
+ descendants of the paragraph ancestor of this text node but not
+ descendants of any frame nodes that are descendants of the current
+ text nodes paragraph.
+ -->
+ <variable name="context"
+ select="$current-paragraph//text()[not(boolean(./ancestor::draw:frame[1]) and count(./ancestor::draw:frame[1] | $frames) = $frame-count)]"/>
+ <variable name="context-size" select="count($context)"/>
+
+ <variable name="context-index">
+ <call-template name="mk-context-index">
+ <with-param name="current-id" select="generate-id(.)"/>
+ <with-param name="context" select="$context"/>
+ <with-param name="test-index" select="1"/>
+ </call-template>
+ </variable>
+
+ <variable name="style-left">
+ <choose>
+ <when test="$context-index &gt; 1">
+ <variable name="left" select="$context[$context-index - 1]"/>
+ <!--
+ The preceding text node is a child of this nodes topmost
+ styled ancestor. This means that the result of the
+ transformation will be directly concatenated.
+ -->
+ <call-template name="mk-style-set">
+ <with-param name="node" select="$left"/>
+ </call-template>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <variable name="style-right">
+ <choose>
+ <when test="$context-index &lt; count($context)">
+ <variable name="right" select="$context[$context-index + 1]"/>
+ <!--
+ The preceding text node is a child of this nodes topmost
+ styled ancestor. This means that the result of the
+ transformation will be directly concatenated.
+ -->
+ <call-template name="mk-style-set">
+ <with-param name="node" select="$right"/>
+ </call-template>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+
+ <variable name="bold"
+ select="($style mod (2 * $BOLD_BIT)) != 0"/>
+ <variable name="italic"
+ select="($style mod (2 * $ITALIC_BIT)) - ($style mod ($ITALIC_BIT)) != 0"/>
+ <variable name="underline"
+ select="($style mod (2 * $UNDERLINE_BIT)) - ($style mod ($UNDERLINE_BIT)) != 0"/>
+ <variable name="superscript"
+ select="($style mod (2 * $SUPERSCRIPT_BIT)) - ($style mod ($SUPERSCRIPT_BIT)) != 0"/>
+ <variable name="subscript"
+ select="($style mod (2 * $SUBSCRIPT_BIT)) - ($style mod ($SUBSCRIPT_BIT)) != 0"/>
+ <variable name="code"
+ select="($style mod (2 * $CODE_BIT)) - ($style mod ($CODE_BIT)) != 0"/>
+ <variable name="typewriter"
+ select="($style mod (2 * $TYPEWRITER_BIT)) - ($style mod ($TYPEWRITER_BIT)) != 0"/>
+
+ <variable name="bold-left"
+ select="($style-left mod (2 * $BOLD_BIT)) != 0"/>
+ <variable name="italic-left"
+ select="($style-left mod (2 * $ITALIC_BIT)) - ($style-left mod ($ITALIC_BIT)) != 0"/>
+ <variable name="underline-left"
+ select="($style-left mod (2 * $UNDERLINE_BIT)) - ($style-left mod ($UNDERLINE_BIT)) != 0"/>
+ <variable name="superscript-left"
+ select="($style-left mod (2 * $SUPERSCRIPT_BIT)) - ($style-left mod ($SUPERSCRIPT_BIT)) != 0"/>
+ <variable name="subscript-left"
+ select="($style-left mod (2 * $SUBSCRIPT_BIT)) - ($style-left mod ($SUBSCRIPT_BIT)) != 0"/>
+ <variable name="typewriter-left"
+ select="($style-left mod (2 * $TYPEWRITER_BIT)) - ($style-left mod ($TYPEWRITER_BIT)) != 0"/>
+
+ <variable name="bold-right"
+ select="($style-right mod (2 * $BOLD_BIT)) != 0"/>
+ <variable name="italic-right"
+ select="($style-right mod (2 * $ITALIC_BIT)) - ($style-right mod ($ITALIC_BIT)) != 0"/>
+ <variable name="underline-right"
+ select="($style-right mod (2 * $UNDERLINE_BIT)) - ($style-right mod ($UNDERLINE_BIT)) != 0"/>
+ <variable name="superscript-right"
+ select="($style-right mod (2 * $SUPERSCRIPT_BIT)) - ($style-right mod ($SUPERSCRIPT_BIT)) != 0"/>
+ <variable name="subscript-right"
+ select="($style-right mod (2 * $SUBSCRIPT_BIT)) - ($style-right mod ($SUBSCRIPT_BIT)) != 0"/>
+ <variable name="typewriter-right"
+ select="($style-right mod (2 * $TYPEWRITER_BIT)) - ($style-right mod ($TYPEWRITER_BIT)) != 0"/>
+
+ <!-- Debugging: Add style infos to the output. -->
+ <!--
+ <value-of select="'{'"/>
+ <value-of select="$style-left"/>
+ <value-of select="'-'"/>
+ <value-of select="$style"/>
+ <value-of select="','"/>
+ <value-of select="$context-size"/>
+ <value-of select="'}'"/>
+ -->
+
+ <if test="$superscript and not($superscript-left) and not(boolean(ancestor::text:note))">
+ <text>&lt;sup&gt;</text>
+ </if>
+ <if test="$subscript and not($subscript-left)">
+ <text>&lt;sub&gt;</text>
+ </if>
+ <if test="not($code) and $typewriter and not($typewriter-left)">
+ <text>&lt;tt&gt;</text>
+ </if>
+ <if test="$underline and not($underline-left)">
+ <text>&lt;u&gt;</text>
+ </if>
+ <if test="$bold and not($bold-left)">
+ <text>'''</text>
+ </if>
+ <if test="$italic and not($italic-left)">
+ <text>''</text>
+ </if>
+
+ <call-template name="render-quoted-text">
+ <with-param name="text" select="."/>
+ </call-template>
+
+ <if test="$italic and not($italic-right)">
+ <text>''</text>
+ </if>
+ <if test="$bold and not($bold-right)">
+ <text>'''</text>
+ </if>
+ <if test="$underline and not($underline-right)">
+ <text>&lt;/u&gt;</text>
+ </if>
+ <if test="not($code) and $typewriter and not($typewriter-right)">
+ <text>&lt;/tt&gt;</text>
+ </if>
+ <if test="$subscript and not($subscript-right)">
+ <text>&lt;/sub&gt;</text>
+ </if>
+ <if test="$superscript and not($superscript-right) and not(boolean(ancestor::text:note))">
+ <text>&lt;/sup&gt;</text>
+ </if>
+
+ <!-- Debugging: Add style details to the output. -->
+ <!--
+ <value-of select="'{'"/>
+ <value-of select="$style"/>
+ <value-of select="'-'"/>
+ <value-of select="$style-right"/>
+ <value-of select="'}'"/>
+ -->
+
+ </when>
+ </choose>
+ </template>
+
+ <!--
+ Function for looking up the position of a node identified by the given
+ 'current-id' within a node set 'context'.
+
+ The search starts with the index 'test-index'. The search is recursive
+ in the 'test-index' argument. To save recursion depth, each recursive call
+ iteratively tests a fixed number of indexes (by loop unrolling).
+ -->
+ <template name="mk-context-index">
+ <param name="current-id"/>
+ <param name="context"/>
+ <param name="test-index"/>
+
+ <variable name="context-size" select="count($context)"/>
+
+ <choose>
+ <when test="context-size &lt; $test-index">
+ </when>
+ <when test="$current-id = generate-id($context[$test-index])">
+ <value-of select="$test-index"/>
+ </when>
+ <when test="context-size &lt; ($test-index + 1)">
+ </when>
+ <when test="$current-id = generate-id($context[$test-index + 1])">
+ <value-of select="$test-index + 1"/>
+ </when>
+ <when test="context-size &lt; ($test-index + 2)">
+ </when>
+ <when test="$current-id = generate-id($context[$test-index + 2])">
+ <value-of select="$test-index + 2"/>
+ </when>
+ <when test="context-size &lt; ($test-index + 3)">
+ </when>
+ <when test="$current-id = generate-id($context[$test-index + 3])">
+ <value-of select="$test-index + 3"/>
+ </when>
+ <when test="context-size &lt; ($test-index + 4)">
+ </when>
+ <when test="$current-id = generate-id($context[$test-index + 4])">
+ <value-of select="$test-index + 4"/>
+ </when>
+ <when test="context-size &lt; ($test-index + 5)">
+ </when>
+ <when test="$current-id = generate-id($context[$test-index + 5])">
+ <value-of select="$test-index + 5"/>
+ </when>
+ <when test="context-size &lt; ($test-index + 6)">
+ </when>
+ <otherwise>
+ <call-template name="mk-context-index">
+ <with-param name="current-id" select="$current-id"/>
+ <with-param name="context" select="$context"/>
+ <with-param name="test-index" select="$test-index + 6"/>
+ </call-template>
+ </otherwise>
+ </choose>
+ </template>
+
+ <template name="render-quoted-text">
+ <param name="text"/>
+
+ <choose>
+ <when test="contains($text, '[[') or starts-with($text, '----') or starts-with($text, '=') or starts-with($text, '*') or starts-with($text, ';') or starts-with($text, '#')">
+ <text>&lt;nowiki&gt;</text>
+ <call-template name="render-encoded-text">
+ <with-param name="text" select="$text"/>
+ </call-template>
+ <text>&lt;/nowiki&gt;</text>
+ </when>
+ <otherwise>
+ <call-template name="render-encoded-text">
+ <with-param name="text" select="$text"/>
+ </call-template>
+ </otherwise>
+ </choose>
+ </template>
+
+ <template name="render-escaped-text">
+ <param name="text"/>
+
+ <choose>
+ <when test="contains($text, '&lt;')">
+ <call-template name="render-encoded-text">
+ <with-param name="text" select="substring-before($text, '&lt;')"/>
+ </call-template>
+ <value-of select="'&amp;lt;'"/>
+ <call-template name="render-escaped-text">
+ <with-param name="text" select="substring-after($text, '&lt;')"/>
+ </call-template>
+ </when>
+ <otherwise>
+ <call-template name="render-encoded-text">
+ <with-param name="text" select="$text"/>
+ </call-template>
+ </otherwise>
+ </choose>
+ </template>
+
+ <template name="render-encoded-text">
+ <param name="text"/>
+
+ <choose>
+ <when test="contains($text, '&#160;')">
+ <value-of select="substring-before($text, '&#160;')"/>
+ <value-of select="'&amp;nbsp;'"/>
+ <call-template name="render-encoded-text">
+ <with-param name="text" select="substring-after($text, '&#160;')"/>
+ </call-template>
+ </when>
+ <otherwise>
+ <value-of select="$text"/>
+ </otherwise>
+ </choose>
+ </template>
+
+ <!--
+ == Wiki styles: bold, italics, ... ==
+ -->
+
+ <template name="mk-style-set">
+ <param name="node"/>
+
+ <choose>
+ <when test="$node/ancestor-or-self::*[@text:style-name]">
+ <variable name="context" select="$node/ancestor-or-self::*[@text:style-name][1]"/>
+ <call-template name="mk-style-set-internal">
+ <with-param name="node" select="$context"/>
+ <with-param name="style" select="key('style-ref', $context/@text:style-name)"/>
+ <with-param name="style-set" select="$NO_STYLE"/>
+ <with-param name="style-mask" select="$NO_STYLE"/>
+ </call-template>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </template>
+
+ <!--
+ Compute the wiki style set that corresponds
+ to the given office style at the given context node.
+
+ @param node
+ A node in which context the style is computed. If neither the given style
+ nor one of its linked styles does specify a style of the given type,
+ ancestor nodes of the given context node are considered.
+ @param style
+ A style:style element node. The style of the requested type is searched
+ in the given style and its linked styles.
+ @style-set
+ A bit set of styles already defined by the context.
+ @style-mask
+ A bit set of styles that must not be taken from the currently inspected
+ style, because those styles are already defined by the context.
+
+ @return A bit set composed of the wiki style constants.
+ -->
+ <template name="mk-style-set-internal">
+ <param name="node"/>
+ <param name="style"/>
+ <param name="style-set"/>
+ <param name="style-mask"/>
+
+ <variable name="text-properties" select="$style/style:text-properties"/>
+
+ <!-- Decompose style-mask into individual bits. -->
+ <variable name="bold-requested"
+ select="($style-mask mod (2 * $BOLD_BIT)) = 0"/>
+ <variable name="italic-requested"
+ select="($style-mask mod (2 * $ITALIC_BIT)) - ($style-mask mod ($ITALIC_BIT)) = 0"/>
+ <variable name="underline-requested"
+ select="($style-mask mod (2 * $UNDERLINE_BIT)) - ($style-mask mod ($UNDERLINE_BIT)) = 0"/>
+ <variable name="superscript-requested"
+ select="($style-mask mod (2 * $SUPERSCRIPT_BIT)) - ($style-mask mod ($SUPERSCRIPT_BIT)) = 0"/>
+ <variable name="subscript-requested"
+ select="($style-mask mod (2 * $SUBSCRIPT_BIT)) - ($style-mask mod ($SUBSCRIPT_BIT)) = 0"/>
+ <variable name="typewriter-requested"
+ select="($style-mask mod (2 * $TYPEWRITER_BIT)) - ($style-mask mod ($TYPEWRITER_BIT)) = 0"/>
+ <variable name="code-requested"
+ select="($style-mask mod (2 * $CODE_BIT)) - ($style-mask mod ($CODE_BIT)) = 0"/>
+ <variable name="center-requested"
+ select="($style-mask mod (2 * $CENTER_BIT)) - ($style-mask mod ($CENTER_BIT)) = 0"/>
+ <variable name="right-requested"
+ select="($style-mask mod (2 * $RIGHT_BIT)) - ($style-mask mod ($RIGHT_BIT)) = 0"/>
+
+ <!-- Extract styles that are not already defined by the context. -->
+ <variable name="bold-style">
+ <choose>
+ <when test="$bold-requested and boolean($text-properties/@fo:font-weight='bold')">
+ <!-- Bold found in current style. -->
+ <value-of select="$BOLD_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <variable name="bold-mask">
+ <choose>
+ <when test="$bold-requested and boolean($text-properties/@fo:font-weight)">
+ <!--
+ Other value than "bold" means that the character style is not
+ bold and no parent style must be considered.
+ -->
+ <value-of select="$BOLD_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+
+ <variable name="italic-style">
+ <choose>
+ <when test="$italic-requested and boolean($text-properties/@fo:font-style='italic')">
+ <!-- Italic found in current style. -->
+ <value-of select="$ITALIC_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <variable name="italic-mask">
+ <choose>
+ <when test="$italic-requested and boolean($text-properties/@fo:font-style)">
+ <!--
+ Other value than "italic" means that the character style is not
+ italic and no parent style must be considered.
+ -->
+ <value-of select="$ITALIC_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+
+ <variable name="underline-style">
+ <choose>
+ <when test="$underline-requested and boolean($text-properties/@style:text-underline-style='solid')">
+ <!-- Underline found in current style. -->
+ <value-of select="$UNDERLINE_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <variable name="underline-mask">
+ <choose>
+ <when test="$underline-requested and boolean($text-properties/@style:text-underline-style='solid')">
+ <!--
+ Other value than "underline" means that the character style is not
+ underline and no parent style must be considered.
+ -->
+ <value-of select="$UNDERLINE_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+
+ <variable name="superscript-style">
+ <choose>
+ <when test="$superscript-requested and contains($text-properties/@style:text-position, 'super')">
+ <value-of select="$SUPERSCRIPT_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <variable name="superscript-mask">
+ <choose>
+ <when test="$superscript-requested and boolean($text-properties/@style:text-position)">
+ <value-of select="$SUPERSCRIPT_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+
+ <variable name="subscript-style">
+ <choose>
+ <when test="$subscript-requested and contains($text-properties/@style:text-position, 'sub')">
+ <value-of select="$SUBSCRIPT_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <variable name="subscript-mask">
+ <choose>
+ <when test="$subscript-requested and boolean($text-properties/@style:text-position)">
+ <value-of select="$SUBSCRIPT_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+
+ <variable name="typewriter-style">
+ <choose>
+ <when test="$typewriter-requested and ($style/@style:family='text') and boolean($text-properties/@style:font-name)">
+ <variable name="font-face"
+ select="key('font-face-ref', $text-properties/@style:font-name)"/>
+ <choose>
+ <when test="$font-face/@style:font-pitch='fixed'">
+ <value-of select="$TYPEWRITER_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <variable name="typewriter-mask">
+ <choose>
+ <!-- Note: Suppress the typewriter style on text within a code paragraph. -->
+ <when test="$typewriter-requested and boolean($text-properties/@style:font-name)">
+ <value-of select="$TYPEWRITER_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+
+ <variable name="code-style">
+ <choose>
+ <when test="$code-requested and ($style/@style:family='paragraph') and boolean($text-properties/@style:font-name)">
+ <variable name="font-face"
+ select="key('font-face-ref', $text-properties/@style:font-name)"/>
+ <choose>
+ <when test="$font-face/@style:font-pitch='fixed' or (boolean(@style:display-name) and contains($CODE_STYLES, $style/@style:display-name))">
+ <value-of select="$CODE_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <variable name="code-mask">
+ <choose>
+ <when test="$code-requested and ($style/@style:family='paragraph') and boolean($text-properties/@style:font-name)">
+ <value-of select="$CODE_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+
+ <variable name="center-style">
+ <choose>
+ <when test="$center-requested and ($style/@style:family='paragraph') and boolean($style/style:paragraph-properties/@fo:text-align='center')">
+ <value-of select="$CENTER_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <variable name="center-mask">
+ <choose>
+ <when test="$center-requested and ($style/@style:family='paragraph') and boolean($style/style:paragraph-properties/@fo:text-align)">
+ <value-of select="$CENTER_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+
+ <variable name="right-style">
+ <choose>
+ <when test="$right-requested and ($style/@style:family='paragraph') and boolean($style/style:paragraph-properties/@fo:text-align='end')">
+ <value-of select="$RIGHT_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+ <variable name="right-mask">
+ <choose>
+ <when test="$center-requested and ($style/@style:family='paragraph') and boolean($style/style:paragraph-properties/@fo:text-align)">
+ <value-of select="$RIGHT_BIT"/>
+ </when>
+ <otherwise>
+ <value-of select="$NO_STYLE"/>
+ </otherwise>
+ </choose>
+ </variable>
+
+
+ <!-- Compute the updated styles and mask. -->
+ <!--
+ Note: The bit masks style-mask, bold-style, italic-style,... are
+ guaranteed to be disjoint, therefore, addition can be use instead
+ of bitwise or (which is missing in XPath). -->
+ <variable name="updated-style"
+ select="$style-set + $bold-style + $italic-style + $underline-style + $superscript-style + $subscript-style + $code-style + $typewriter-style + $center-style + $right-style"/>
+ <variable name="updated-mask"
+ select="$style-mask + $bold-mask + $italic-mask + $underline-mask + $superscript-mask + $subscript-mask + $code-mask + $typewriter-mask + $center-mask + $right-mask"/>
+
+ <!-- Inspect linked and nested styles. -->
+ <choose>
+ <when test="boolean($style/@style:parent-style-name)">
+ <!-- Look through the style, the current style is based on. -->
+ <call-template name="mk-style-set-internal">
+ <with-param name="node" select="$node"/>
+ <with-param name="style" select="key('style-ref', $style/@style:parent-style-name)"/>
+ <with-param name="style-set" select="$updated-style"/>
+ <with-param name="style-mask" select="$updated-mask"/>
+ </call-template>
+ </when>
+ <otherwise>
+ <variable name="ancestors" select="$node/ancestor::*[@text:style-name][1]"/>
+
+ <!-- Debugging: Print currently inspected style. -->
+ <!--
+ <message>
+ <value-of select="'{'"/>
+ <value-of select="$style/@style:name"/>
+ <value-of select="','"/>
+ <value-of select="$updated-style"/>
+ <value-of select="','"/>
+ <value-of select="$updated-mask"/>
+ <value-of select="','"/>
+ <value-of select="local-name($ancestors)"/>
+ <value-of select="',('"/>
+ <value-of select="$node"/>
+ <value-of select="')'"/>
+ <value-of select="'}'"/>
+ </message>
+ -->
+
+ <!--
+ If there is an ancestor that has a style, use that style,
+ otherwise, a style is not found. -->
+ <choose>
+ <when test="boolean($ancestors)">
+ <!-- Look through the style of the nearest ancestor that has a style. -->
+ <call-template name="mk-style-set-internal">
+ <with-param name="node" select="$ancestors"/>
+ <with-param name="style" select="key('style-ref', $ancestors/@text:style-name)"/>
+ <with-param name="style-set" select="$updated-style"/>
+ <with-param name="style-mask" select="$updated-mask"/>
+ </call-template>
+ </when>
+ <otherwise>
+ <!-- No more styles to inspect. Return the result. -->
+ <value-of select="$updated-style"/>
+ </otherwise>
+ </choose>
+ </otherwise>
+ </choose>
+ </template>
+
+
+ <!--
+ == Descending the tree ==
+ -->
+
+ <template match="/">
+ <apply-templates/>
+ <value-of select="$NL"/>
+ <if test="boolean(//text:note[@text:note-class='footnote'])">
+ <value-of select="$NL"/>
+ <text>----</text>
+ <value-of select="$NL"/>
+ <text>&lt;references/&gt;</text>
+ <value-of select="$NL"/>
+ </if>
+ </template>
+
+ <template match="office:document-content">
+ <apply-templates/>
+ </template>
+
+ <template match="office:body">
+ <apply-templates/>
+ </template>
+
+ <template match="text:tracked-changes">
+ <!-- Ignore change history. -->
+ </template>
+
+ <template match="office:* | text:* | draw:text-box | draw:a">
+ <apply-templates/>
+ </template>
+
+ <template match="node()">
+ </template>
+</stylesheet>
+
+<!--
+ Local Variables:
+ tab-width: 4
+ sgml-indent-step: 4
+ End:
+-->
diff --git a/swext/mediawiki/src/registry/data/org/openoffice/Office/Addons.xcu b/swext/mediawiki/src/registry/data/org/openoffice/Office/Addons.xcu
new file mode 100644
index 0000000000..854c7b94c4
--- /dev/null
+++ b/swext/mediawiki/src/registry/data/org/openoffice/Office/Addons.xcu
@@ -0,0 +1,58 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Addons" oor:package="org.openoffice.Office">
+ <node oor:name="AddonUI">
+ <node oor:name="OfficeMenuBarMerging">
+ <node oor:name="com.sun.star.wiki" oor:op="replace">
+ <node oor:name="S1" oor:op="replace">
+ <prop oor:name="MergePoint">
+ <value>.uno:PickList\.uno:SendToMenu\.uno:SendMailDocAsPDF</value>
+ </prop>
+ <prop oor:name="MergeCommand">
+ <value>AddAfter</value>
+ </prop>
+ <prop oor:name="MergeFallback">
+ <value>AddLast</value>
+ </prop>
+ <prop oor:name="MergeContext" oor:type="xs:string">
+ <value>com.sun.star.text.TextDocument,com.sun.star.text.WebDocument</value>
+ </prop>
+ <node oor:name="MenuItems">
+ <node oor:name="M1" oor:op="replace">
+ <prop oor:name="URL">
+ <value>private:separator</value>
+ </prop>
+ </node>
+ <node oor:name="M2" oor:op="replace">
+ <prop oor:name="Title">
+ <value xml:lang="en-US">To Media~Wiki...</value>
+ </prop>
+ <prop oor:name="URL">
+ <value>vnd.com.sun.star.wiki:send</value>
+ </prop>
+ <prop oor:name="Target" oor:type="xs:string">
+ <value>_self</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/swext/mediawiki/src/registry/data/org/openoffice/Office/Custom/WikiExtension.xcu b/swext/mediawiki/src/registry/data/org/openoffice/Office/Custom/WikiExtension.xcu
new file mode 100644
index 0000000000..729f80b560
--- /dev/null
+++ b/swext/mediawiki/src/registry/data/org/openoffice/Office/Custom/WikiExtension.xcu
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="WikiExtension" oor:package="org.openoffice.Office.Custom">
+ <node oor:name="SpecialData">
+ </node>
+
+ <node oor:name="ConnectionList">
+ </node>
+
+ <node oor:name="RecentDocs">
+ </node>
+
+ <node oor:name="Settings">
+ <prop oor:name="PreselectShowBrowser">
+ <value>true</value>
+ </prop>
+ </node>
+ <node oor:name="Strings">
+ <prop oor:name="GeneralSendError">
+ <value xml:lang="en-US">The operation 'Send to MediaWiki' could not be completed successfully.</value>
+ </prop>
+ <prop oor:name="NoWikiFilter">
+ <value xml:lang="en-US">The MediaWiki export filter cannot be found. Choose 'Tools-XML Filter Settings' to install the filter, or use the setup to install the component.</value>
+ </prop>
+ <prop oor:name="NoConnectionToURL">
+ <value xml:lang="en-US">A connection to the MediaWiki system at '$ARG1' could not be created.</value>
+ </prop>
+ <prop oor:name="WrongLogin">
+ <value xml:lang="en-US">User name or password is incorrect. Please try again, or leave the fields blank for an anonymous connection.</value>
+ </prop>
+ <prop oor:name="InvalidURL">
+ <value xml:lang="en-US">A connection could not be created because the URL is invalid.</value>
+ </prop>
+ <prop oor:name="NoURL">
+ <value xml:lang="en-US">Specify a MediaWiki server by providing a URL.</value>
+ </prop>
+ <prop oor:name="CancelSending">
+ <value xml:lang="en-US">The transfer has been interrupted. Please check the integrity of the wiki article.</value>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_UrlLabel">
+ <value xml:lang="en-US">U~RL</value>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_UsernameLabel">
+ <value xml:lang="en-US">~Username</value>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_PasswordLabel">
+ <value xml:lang="en-US">~Password</value>
+ </prop>
+ <prop oor:name="Dlg_SendTitle">
+ <value xml:lang="en-US">Send to MediaWiki</value>
+ </prop>
+ <prop oor:name="Dlg_WikiArticle">
+ <value xml:lang="en-US">Wiki article</value>
+ </prop>
+ <prop oor:name="Dlg_No">
+ <value xml:lang="en-US">No</value>
+ </prop>
+ <prop oor:name="Dlg_OK">
+ <value xml:lang="en-US">OK</value>
+ </prop>
+ <prop oor:name="Dlg_Yes">
+ <value xml:lang="en-US">Yes</value>
+ </prop>
+ <prop oor:name="Dlg_AddButton">
+ <value xml:lang="en-US">~Add...</value>
+ </prop>
+ <prop oor:name="Dlg_EditButton">
+ <value xml:lang="en-US">~Edit...</value>
+ </prop>
+ <prop oor:name="Dlg_SendButton">
+ <value xml:lang="en-US">~Send</value>
+ </prop>
+ <prop oor:name="Dlg_RemoveButton">
+ <value xml:lang="en-US">~Remove</value>
+ </prop>
+ <prop oor:name="Dlg_NewWikiPage_Label1">
+ <value xml:lang="en-US">A wiki article with the title '$ARG1' does not exist yet. Do you want to create a new article with that name?</value>
+ </prop>
+ <prop oor:name="Dlg_SendToMediaWiki_Label1">
+ <value xml:lang="en-US">Media~Wiki Server</value>
+ </prop>
+ <prop oor:name="Dlg_SendToMediaWiki_Label2">
+ <value xml:lang="en-US">~Title</value>
+ </prop>
+ <prop oor:name="Dlg_SendToMediaWiki_Label3">
+ <value xml:lang="en-US">S~ummary</value>
+ </prop>
+ <prop oor:name="Dlg_SendToMediaWiki_MinorCheck">
+ <value xml:lang="en-US">This is a ~minor edit</value>
+ </prop>
+ <prop oor:name="Dlg_SendToMediaWiki_BrowserCheck">
+ <value xml:lang="en-US">Show in web ~browser</value>
+ </prop>
+ <prop oor:name="UnknownCert">
+ <value xml:lang="en-US">The certificate of the selected site is unknown.</value>
+ </prop>
+ <prop oor:name="Dlg_MediaWiki_Title">
+ <value xml:lang="en-US">MediaWiki</value>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_AccountLine">
+ <value xml:lang="en-US">Account</value>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_WikiLine">
+ <value xml:lang="en-US">MediaWiki Server</value>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_SaveBox">
+ <value xml:lang="en-US">~Save password</value>
+ </prop>
+ <prop oor:name="Dlg_MediaWiki_Extension_String">
+ <value xml:lang="en-US">Wiki Publisher</value>
+ </prop>
+ <prop oor:name="Dlg_WikiPageExists_Label1">
+ <value xml:lang="en-US">A wiki article with the title '$ARG1' already exists.&#13;&#13;Do you want to replace the current article with your article?&#13;&#13;</value>
+ </prop>
+ </node>
+</oor:component-data>
diff --git a/swext/mediawiki/src/registry/data/org/openoffice/Office/OptionsDialog.xcu b/swext/mediawiki/src/registry/data/org/openoffice/Office/OptionsDialog.xcu
new file mode 100644
index 0000000000..2b35ced08f
--- /dev/null
+++ b/swext/mediawiki/src/registry/data/org/openoffice/Office/OptionsDialog.xcu
@@ -0,0 +1,41 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+<oor:component-data oor:name="OptionsDialog" oor:package="org.openoffice.Office" xmlns:oor="http://openoffice.org/2001/registry">
+ <node oor:name="Nodes">
+ <node oor:name="Internet" oor:op="fuse">
+ <node oor:name="Leaves">
+ <node oor:name="com.sun.star.wiki.options" oor:op="fuse">
+ <prop oor:name="Id">
+ <value>com.sun.wiki-publisher</value>
+ </prop>
+ <prop oor:name="Label">
+ <value xml:lang="en-US">MediaWiki</value>
+ </prop>
+ <prop oor:name="OptionsPage">
+ <value>%origin%/WikiEditor/Settings.xdl</value>
+ </prop>
+ <prop oor:name="EventHandlerService">
+ <value>com.sun.star.wiki.WikiOptionsEventHandlerImpl</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+</oor:component-data>
+
diff --git a/swext/mediawiki/src/registry/data/org/openoffice/Office/Paths.xcu b/swext/mediawiki/src/registry/data/org/openoffice/Office/Paths.xcu
new file mode 100644
index 0000000000..01763bfd66
--- /dev/null
+++ b/swext/mediawiki/src/registry/data/org/openoffice/Office/Paths.xcu
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Paths" oor:package="org.openoffice.Office">
+ <node oor:name="Paths">
+ <node oor:name="Template" oor:op="fuse">
+ <node oor:name="InternalPaths">
+ <node oor:name="%origin%/templates" oor:op="fuse"/>
+ </node>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/swext/mediawiki/src/registry/data/org/openoffice/Office/ProtocolHandler.xcu b/swext/mediawiki/src/registry/data/org/openoffice/Office/ProtocolHandler.xcu
new file mode 100644
index 0000000000..8337a2abcf
--- /dev/null
+++ b/swext/mediawiki/src/registry/data/org/openoffice/Office/ProtocolHandler.xcu
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+<oor:component-data oor:name="ProtocolHandler" oor:package="org.openoffice.Office" 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="HandlerSet">
+ <node oor:name="com.sun.star.wiki.WikiEditorImpl" oor:op="replace">
+ <prop oor:name="Protocols" oor:type="oor:string-list">
+ <value>vnd.com.sun.star.wiki:*</value>
+ </prop>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/swext/mediawiki/src/registry/data/org/openoffice/TypeDetection/Filter.xcu b/swext/mediawiki/src/registry/data/org/openoffice/TypeDetection/Filter.xcu
new file mode 100644
index 0000000000..3309b50382
--- /dev/null
+++ b/swext/mediawiki/src/registry/data/org/openoffice/TypeDetection/Filter.xcu
@@ -0,0 +1,47 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+<!DOCTYPE oor:component-data SYSTEM "../../../../../../../../officecfg/registry/component-update.dtd">
+<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:package="org.openoffice.TypeDetection" oor:name="Filter">
+ <node oor:name="Filters">
+ <node oor:name="MediaWiki" oor:op="fuse">
+ <prop oor:name="FileFormatVersion"><value>0</value></prop>
+ <prop oor:name="Type"><value>MediaWiki</value></prop>
+ <prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop>
+ <prop oor:name="UIComponent"/>
+ <prop oor:name="UserData"><value oor:separator=",">com.sun.star.documentconversion.XSLTFilter,,,com.sun.star.comp.Writer.XMLOasisExporter,,%origin%/filter/odt2mediawiki.xsl</value></prop>
+ <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
+ <prop oor:name="UIName">
+ <value xml:lang="x-default">MediaWiki</value>
+ </prop>
+ <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
+ </node>
+ <node oor:name="MediaWiki_Web" oor:op="fuse">
+ <prop oor:name="FileFormatVersion"><value>0</value></prop>
+ <prop oor:name="Type"><value>MediaWiki</value></prop>
+ <prop oor:name="DocumentService"><value>com.sun.star.text.WebDocument</value></prop>
+ <prop oor:name="UIComponent"/>
+ <prop oor:name="UserData"><value oor:separator=",">com.sun.star.documentconversion.XSLTFilter,,,com.sun.star.comp.Writer.XMLOasisExporter,,%origin%/filter/odt2mediawiki.xsl</value></prop>
+ <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
+ <prop oor:name="UIName">
+ <value xml:lang="x-default">MediaWiki</value>
+ </prop>
+ <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/swext/mediawiki/src/registry/data/org/openoffice/TypeDetection/Types.xcu b/swext/mediawiki/src/registry/data/org/openoffice/TypeDetection/Types.xcu
new file mode 100644
index 0000000000..15e4f85004
--- /dev/null
+++ b/swext/mediawiki/src/registry/data/org/openoffice/TypeDetection/Types.xcu
@@ -0,0 +1,35 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+<!DOCTYPE oor:component-data SYSTEM "../../../../../../../../officecfg/registry/component-update.dtd">
+<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:package="org.openoffice.TypeDetection" oor:name="Types">
+ <node oor:name="Types">
+ <node oor:name="MediaWiki" oor:op="fuse">
+ <prop oor:name="DetectService"><value>com.sun.star.comp.filters.XMLFilterDetect</value></prop>
+ <prop oor:name="URLPattern"/>
+ <prop oor:name="Extensions"><value>txt</value></prop>
+ <prop oor:name="MediaType"/>
+ <prop oor:name="Preferred"><value>false</value></prop>
+ <prop oor:name="PreferredFilter"/>
+ <prop oor:name="UIName">
+ <value xml:lang="x-default">MediaWiki</value>
+ </prop>
+ <prop oor:name="ClipboardFormat"/>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/swext/mediawiki/src/registry/schema/org/openoffice/Office/Custom/WikiExtension.xcs b/swext/mediawiki/src/registry/schema/org/openoffice/Office/Custom/WikiExtension.xcs
new file mode 100644
index 0000000000..d41478c57c
--- /dev/null
+++ b/swext/mediawiki/src/registry/schema/org/openoffice/Office/Custom/WikiExtension.xcs
@@ -0,0 +1,188 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+<oor:component-schema
+ xmlns:oor="http://openoffice.org/2001/registry"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ oor:name="WikiExtension"
+ oor:package="org.openoffice.Office.Custom"
+ xml:lang="en-US">
+ <info>
+ <desc>Configuration parameters for the accounts.</desc>
+ </info>
+
+ <templates>
+ <group oor:name="RequestArgument">
+ <info><desc>An argument for a request.</desc></info>
+ <prop oor:name="Value" oor:type="xs:string">
+ <info><desc>The value of the argument.</desc></info>
+ </prop>
+ </group>
+
+ <group oor:name="WikiServerSpecialData">
+ <info><desc>The smart configuration for the MediaWikiServer.</desc></info>
+ <prop oor:name="AllowUnknownCertificate" oor:type="xs:boolean">
+ <info><desc>The value of the argument.</desc></info>
+ </prop>
+ <set oor:name="AdditionalLoginArguments" oor:node-type="RequestArgument">
+ <info><desc>The additional arguments that can be used on login. The name of an entry is the argument name.</desc></info>
+ </set>
+ </group>
+
+ <group oor:name="ConnectionURL">
+ <info><desc>The name of the entry is a connection URL of a wiki server.</desc></info>
+ <prop oor:name="UserName" oor:type="xs:string">
+ <info><desc>The UserName that is used to access the URL.</desc></info>
+ </prop>
+ </group>
+
+ <group oor:name="Document">
+ <info><desc>Wiki Document</desc></info>
+ <prop oor:name="Url" oor:type="xs:string">
+ <info><desc>Main URL for this Wiki</desc></info>
+ </prop>
+ <prop oor:name="Doc" oor:type="xs:string">
+ <info><desc>The Document name</desc></info>
+ </prop>
+ <prop oor:name="CompleteUrl" oor:type="xs:string">
+ <info><desc>Identifier</desc></info>
+ </prop>
+ </group>
+ </templates>
+
+ <component>
+ <set oor:name="SpecialData" oor:node-type="WikiServerSpecialData">
+ <info><desc>The set of smart configurations for MediaWiki Servers.</desc></info>
+ </set>
+ <set oor:name="ConnectionList" oor:node-type="ConnectionURL">
+ <info><desc>The list of the MediaWiki servers.</desc></info>
+ </set>
+ <set oor:name="RecentDocs" oor:node-type="Document">
+ <info><desc>The recently stored documents.</desc></info>
+ </set>
+ <group oor:name="Settings">
+ <info><desc>The addon related settings.</desc></info>
+ <prop oor:name="PreselectShowBrowser" oor:type="xs:boolean">
+ <info><desc>Specifies whether "Show in webbrowser" checkbox should be preselected.</desc></info>
+ </prop>
+ </group>
+ <group oor:name="Strings">
+ <info>
+ <desc>Contains the strings that should be localized</desc>
+ </info>
+ <prop oor:name="GeneralSendError" oor:type="xs:string" oor:localized="true">
+ <info><desc>The general error shown in case the document could not be sent to the wiki server.</desc></info>
+ </prop>
+ <prop oor:name="NoWikiFilter" oor:type="xs:string" oor:localized="true">
+ <info><desc>The error is shown in case wiki filter is not available.</desc></info>
+ </prop>
+ <prop oor:name="NoConnectionToURL" oor:type="xs:string" oor:localized="true">
+ <info><desc>The error is shown in case no wiki system was found on specified URL.</desc></info>
+ </prop>
+ <prop oor:name="WrongLogin" oor:type="xs:string" oor:localized="true">
+ <info><desc>The error is shown in case user name or password is incorrect.</desc></info>
+ </prop>
+ <prop oor:name="InvalidURL" oor:type="xs:string" oor:localized="true">
+ <info><desc>The error is shown in case the provided URL has invalid syntax.</desc></info>
+ </prop>
+ <prop oor:name="NoURL" oor:type="xs:string" oor:localized="true">
+ <info><desc>The error is shown in case no wiki server was specified.</desc></info>
+ </prop>
+ <prop oor:name="CancelSending" oor:type="xs:string" oor:localized="true">
+ <info><desc>The error is shown in case transfer was interrupted by user. The user is notified that the integrity of the wiki article should be checked.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_SendTitle" oor:type="xs:string" oor:localized="true">
+ <info><desc>The title of the send dialog.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_WikiArticle" oor:type="xs:string" oor:localized="true">
+ <info><desc>The dialog string used to border the wiki article related information.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_No" oor:type="xs:string" oor:localized="true">
+ <info><desc>"No" button in dialog.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_OK" oor:type="xs:string" oor:localized="true">
+ <info><desc>"Ok" button in dialog.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_Yes" oor:type="xs:string" oor:localized="true">
+ <info><desc>"Yes" button in dialog.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_AddButton" oor:type="xs:string" oor:localized="true">
+ <info><desc>"Add..." button text.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_EditButton" oor:type="xs:string" oor:localized="true">
+ <info><desc>"Edit..." button text.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_SendButton" oor:type="xs:string" oor:localized="true">
+ <info><desc>"Send" button text.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_RemoveButton" oor:type="xs:string" oor:localized="true">
+ <info><desc>"Remove" button text.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_UrlLabel" oor:type="xs:string" oor:localized="true">
+ <info><desc>"URL" label.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_UsernameLabel" oor:type="xs:string" oor:localized="true">
+ <info><desc>"Username" label.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_PasswordLabel" oor:type="xs:string" oor:localized="true">
+ <info><desc>"Password" label.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_NewWikiPage_Label1" oor:type="xs:string" oor:localized="true">
+ <info><desc>The text asking whether a new wiki page should be created.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_SendToMediaWiki_Label1" oor:type="xs:string" oor:localized="true">
+ <info><desc>The label referring to the MediaWiki server selection.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_SendToMediaWiki_Label2" oor:type="xs:string" oor:localized="true">
+ <info><desc>The label referring to the input of wiki article title.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_SendToMediaWiki_Label3" oor:type="xs:string" oor:localized="true">
+ <info><desc>The label referring to the comments input.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_SendToMediaWiki_MinorCheck" oor:type="xs:string" oor:localized="true">
+ <info><desc>Text for checkbox specifying whether it is a minor input.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_SendToMediaWiki_BrowserCheck" oor:type="xs:string" oor:localized="true">
+ <info><desc>Text for checkbox specifying whether the article should be shown in browser after editing.</desc></info>
+ </prop>
+ <prop oor:name="UnknownCert" oor:type="xs:string" oor:localized="true">
+ <info><desc>The error is shown in case a wiki site is accessed using https and has an unknown certificate.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_MediaWiki_Title" oor:type="xs:string" oor:localized="true">
+ <info><desc>"MediaWiki" string that is used as title in some dialogs.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_AccountLine" oor:type="xs:string" oor:localized="true">
+ <info><desc>The text bordering the account information in the dialog.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_WikiLine" oor:type="xs:string" oor:localized="true">
+ <info><desc>The text bordering wiki server information in the dialog.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_EditSetting_SaveBox" oor:type="xs:string" oor:localized="true">
+ <info><desc>The checkbox specifying whether the password should be stored using the password container.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_MediaWiki_Extension_String" oor:type="xs:string" oor:localized="true">
+ <info><desc>The string containing the name of the extension.</desc></info>
+ </prop>
+ <prop oor:name="Dlg_WikiPageExists_Label1" oor:type="xs:string" oor:localized="true">
+ <info><desc>The text asking whether an existing wiki page should be overwritten.</desc></info>
+ </prop>
+ </group>
+ </component>
+
+</oor:component-schema>