[ooo-build-commit] patches/dev300

Thorsten Behrens thorsten at kemper.freedesktop.org
Thu Oct 1 10:04:19 PDT 2009


 patches/dev300/apply                      |    5 
 patches/dev300/writer-doc-comparison.diff | 3238 ++++++++++++++++++++++++++++++
 2 files changed, 3242 insertions(+), 1 deletion(-)

New commits:
commit 656fd190aaf7692db3dd7e2dd1bd0d6d700add8b
Author: Thorsten Behrens <thb at openoffice.org>
Date:   Fri Oct 2 12:27:45 2009 +0200

    Tzvetelina Tzeneva's GSoC project: doc comparison for writer
    
    * patches/dev300/apply: added patch in new experimental section
    * patches/dev300/writer-doc-comparison.diff: the full patch

diff --git a/patches/dev300/apply b/patches/dev300/apply
index bf27bba..681c102 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -35,7 +35,7 @@ Experimental: VBAUntested, ArkOnlyExperimental, \
 	      UnitBootstrap, RadioButtons, UnstableLibwpd, WWInProgress, \
 	      KDE4Experimental, MinGW, CalcExperimental, Mono24, \
 	      OOXMLExportExperimental, CrossWin32Patches, AutoLayout, \
-		  WriterNavigation
+		  WriterNavigation, WriterDocComparison
 DebianLooseSections: DebianBaseNoHelpContent
 # Optional sections
 Optional : DejaVuFonts, NovellOnlyExtensionFixes, Win32OnlyExtensionFixes, Linux32OnlyExtensionFixes
@@ -3486,6 +3486,9 @@ impress-autolayout.diff, cocofan
 [ WriterNavigation ]
 writer-navigation-buttons.diff, ovcica
 
+[ WriterDocComparison ]
+writer-doc-comparison.diff, tzvetelina
+
 [ MySQL ]
 cws-mysqlnative-20090916.diff
 
diff --git a/patches/dev300/writer-doc-comparison.diff b/patches/dev300/writer-doc-comparison.diff
new file mode 100644
index 0000000..e3678a3
--- /dev/null
+++ b/patches/dev300/writer-doc-comparison.diff
@@ -0,0 +1,3238 @@
+Tzvetelinas gsoc project - writer document comparison
+
+From: Thorsten Behrens <thb at openoffice.org>
+
+
+---
+
+ helpcontent2/source/text/shared/00/00000406.xhp    |    2 
+ .../source/text/shared/optionen/01040000.xhp       |    1 
+ .../source/text/shared/optionen/comparisonopt.xhp  |   77 ++
+ .../source/text/shared/optionen/makefile.mk        |    3 
+ helpcontent2/util/swriter/makefile.mk              |    1 
+ .../schema/org/openoffice/Office/Writer.xcs        |   30 +
+ svx/inc/svx/dialogs.hrc                            |    1 
+ svx/inc/svx/rsiditem.hxx                           |   57 +
+ svx/inc/svx/svxenum.hxx                            |    6 
+ svx/prj/d.lst                                      |    1 
+ svx/source/dialog/treeopt.cxx                      |    1 
+ svx/source/dialog/treeopt.src                      |    1 
+ svx/source/items/textitem.cxx                      |   39 +
+ sw/inc/cmdid.h                                     |    1 
+ sw/inc/doc.hxx                                     |   10 
+ sw/inc/globals.hrc                                 |    1 
+ sw/inc/helpid.h                                    |    1 
+ sw/inc/hintids.hxx                                 |  143 +--
+ sw/inc/modcfg.hxx                                  |   41 +
+ sw/inc/ndtxt.hxx                                   |    7 
+ sw/inc/swmodule.hxx                                |   10 
+ sw/inc/txatbase.hxx                                |    7 
+ sw/inc/undobj.hxx                                  |    1 
+ sw/inc/unoprnms.hxx                                |    4 
+ sw/source/core/bastyp/init.cxx                     |   11 
+ sw/source/core/doc/doc.cxx                         |   73 ++
+ sw/source/core/doc/doccomp.cxx                     |  966 +++++++++++++++++++-
+ sw/source/core/doc/docnew.cxx                      |    9 
+ sw/source/core/edit/editsh.cxx                     |    9 
+ sw/source/core/frmedt/fecopy.cxx                   |   21 
+ sw/source/core/text/atrstck.cxx                    |    4 
+ sw/source/core/txtnode/ndtxt.cxx                   |   41 +
+ sw/source/core/undo/unspnd.cxx                     |    4 
+ sw/source/core/unocore/unomap.cxx                  |    2 
+ sw/source/core/unocore/unoprnms.cxx                |    2 
+ sw/source/filter/ascii/parasc.cxx                  |    3 
+ sw/source/filter/html/css1atr.cxx                  |    3 
+ sw/source/filter/html/htmlatr.cxx                  |    2 
+ sw/source/filter/rtf/rtfatr.cxx                    |    3 
+ sw/source/filter/ww8/ww8atr.cxx                    |    3 
+ sw/source/ui/app/appopt.cxx                        |    1 
+ sw/source/ui/app/docsh.cxx                         |    3 
+ sw/source/ui/app/swmodul1.cxx                      |   40 +
+ sw/source/ui/config/modcfg.cxx                     |   89 ++
+ sw/source/ui/config/optdlg.hrc                     |    8 
+ sw/source/ui/config/optdlg.src                     |   74 ++
+ sw/source/ui/config/optpage.cxx                    |  137 +++
+ sw/source/ui/dialog/swdlgfact.cxx                  |    5 
+ sw/source/ui/inc/optpage.hxx                       |   28 +
+ sw/source/ui/uno/SwXDocumentSettings.cxx           |   28 +
+ xmloff/inc/xmloff/xmltoken.hxx                     |    2 
+ xmloff/inc/xmloff/xmltypes.hxx                     |    1 
+ xmloff/inc/xmloff/xmluconv.hxx                     |    8 
+ xmloff/source/core/xmltoken.cxx                    |    2 
+ xmloff/source/core/xmluconv.cxx                    |   28 +
+ xmloff/source/style/prhdlfac.cxx                   |    3 
+ xmloff/source/style/xmlbahdl.cxx                   |   42 +
+ xmloff/source/style/xmlbahdl.hxx                   |   12 
+ xmloff/source/text/txtprmap.cxx                    |    8 
+ 59 files changed, 1967 insertions(+), 154 deletions(-)
+ create mode 100644 helpcontent2/source/text/shared/optionen/comparisonopt.xhp
+ create mode 100644 svx/inc/svx/rsiditem.hxx
+
+
+diff --git helpcontent2/source/text/shared/00/00000406.xhp helpcontent2/source/text/shared/00/00000406.xhp
+index cd019d9..f49bc03 100644
+--- helpcontent2/source/text/shared/00/00000406.xhp
++++ helpcontent2/source/text/shared/00/00000406.xhp
+@@ -297,6 +297,8 @@
+ </variable></paragraph>
+ <paragraph role="paragraph" id="par_id3147005" xml-lang="en-US" l10n="U" oldref="101"><variable id="registeraenderungen">Open a text document, choose <emph>Tools - Options - %PRODUCTNAME Writer - Changes</emph>
+ </variable></paragraph>
++<paragraph role="paragraph" id="par_id3147006" xml-lang="en-US" l10n="U"><variable id="comparisonoptions">Open a text document, choose <emph>Tools - Options - %PRODUCTNAME Writer - Comparison</emph>
++</variable></paragraph>
+ <paragraph role="paragraph" id="par_id3159333" xml-lang="en-US" l10n="U" oldref="48"><variable id="webbrowser1">Open an HTML document, choose <emph>Tools - Options - %PRODUCTNAME Writer/Web</emph>
+ </variable></paragraph>
+ <paragraph role="paragraph" id="par_id3149448" xml-lang="en-US" l10n="U" oldref="139"><variable id="hinter">Open an HTML document, choose <emph>Tools - Options - %PRODUCTNAME Writer/Web - Background</emph>
+diff --git helpcontent2/source/text/shared/optionen/01040000.xhp helpcontent2/source/text/shared/optionen/01040000.xhp
+index ed4aee9..3354f04 100644
+--- helpcontent2/source/text/shared/optionen/01040000.xhp
++++ helpcontent2/source/text/shared/optionen/01040000.xhp
+@@ -65,6 +65,7 @@
+ <embed href="text/shared/optionen/01040400.xhp#drucken"/>
+ <embed href="text/shared/optionen/01040500.xhp#tabelle"/>
+ <embed href="text/shared/optionen/01040700.xhp#aenderungen"/>
++<embed href="text/shared/optionen/comparisonopt.xhp#comparison"/>
+ <embed href="text/shared/optionen/01041000.xhp#compatibility"/>
+ <embed href="text/shared/optionen/01041100.xhp#autocaption"/>
+ <embed href="text/shared/optionen/mailmerge.xhp#mailmerge"/>
+diff --git helpcontent2/source/text/shared/optionen/comparisonopt.xhp helpcontent2/source/text/shared/optionen/comparisonopt.xhp
+new file mode 100644
+index 0000000..b7fc427
+--- /dev/null
++++ helpcontent2/source/text/shared/optionen/comparisonopt.xhp
+@@ -0,0 +1,77 @@
++<?xml version="1.0" encoding="UTF-8"?>
++
++
++<!--
++ ***********************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ * 
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: comparisonopt.xhp,v $
++ * $Revision: 1.0 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************
++ -->
++	
++<helpdocument version="1.0">
++<meta>
++<topic id="textsharedoptionencomparexml" indexer="include" status="PUBLISH">
++<title id="tit" xml-lang="en-US">Comparison</title>
++<filename>/text/shared/optionen/comparisonopt.xhp</filename>
++</topic>
++<history>
++<created date="2009-08-04T00:00:00">New file created</created>
++<lastedited date="2009-08-04T16:30:58">...</lastedited>
++</history>
++</meta>
++<body>
++<section id="comparison">
++<bookmark xml-lang="en-US" branch="hid/HID_COMPARISON_OPT" id="bm_id3149795" localize="false"/>
++<paragraph role="heading" id="hd_id3153823" xml-lang="en-US" level="1" l10n="U"><link href="text/shared/optionen/comparisonopt.xhp" name="Comparison">Comparison</link></paragraph>
++<paragraph role="paragraph" id="par_id3149416" xml-lang="en-US" l10n="U"><ahelp hid="HID_COMPARISON_OPT">Specifies the settings for comparing two documents.</ahelp></paragraph>
++</section>
++<paragraph role="paragraph" id="par_id3156153" xml-lang="en-US" l10n="U">To compare the current document with another one choose <link href="text/shared/01/02240000.xhp" name="Edit - Compare Document"><emph>Edit - Compare Document</emph></link>.</paragraph>
++<section id="howtoget">
++  <embed href="text/shared/00/00000406.xhp#comparisonoptions"/>
++</section>
++<paragraph role="heading" id="hd_id3155419" xml-lang="en-US" level="2" l10n="U">Compare Documents</paragraph>
++<paragraph role="paragraph" id="par_id3144510" xml-lang="en-US" l10n="U">Specifies the mode for comparing two documents.</paragraph>
++<bookmark xml-lang="en-US" branch="hid/SW:RADIOBUTTON:TP_COMPARISON_OPT:RB_AUTO" id="bm_id3153896" localize="false"/>
++<paragraph role="heading" id="hd_id3148550" xml-lang="en-US" level="3" l10n="U">Auto</paragraph>
++<paragraph role="paragraph" id="par_id3154758" xml-lang="en-US" l10n="U"><ahelp hid="SW:RADIOBUTTON:TP_COMPARISON_OPT:RB_AUTO">Use the most appropirate comparison settings for the current document.</ahelp></paragraph>
++<bookmark xml-lang="en-US" branch="hid/SW:RADIOBUTTON:TP_COMPARISON_OPT:RB_CHAR" id="bm_id3150358" localize="false"/>
++<paragraph role="heading" id="hd_id3152812" xml-lang="en-US" level="3" l10n="U">By word</paragraph>
++<paragraph role="paragraph" id="par_id3154365" xml-lang="en-US" l10n="U"><ahelp hid="SW:RADIOBUTTON:TP_COMPARISON_OPT:RB_CHAR">Compare documents with a word as the basic unit.</ahelp></paragraph>
++<bookmark xml-lang="en-US" branch="hid/SW:RADIOBUTTON:TP_COMPARISON_OPT:RB_WORD" id="bm_id3149203" localize="false"/>
++<paragraph role="heading" id="hd_id3148674" xml-lang="en-US" level="3" l10n="U">By character</paragraph>
++<paragraph role="paragraph" id="par_id3151042" xml-lang="en-US" l10n="U"><ahelp hid="SW:RADIOBUTTON:TP_COMPARISON_OPT:RB_WORD">Compare documents with a character as the basic unit.</ahelp></paragraph>
++<paragraph role="heading" id="hd_id3145607" xml-lang="en-US" level="2" l10n="U">Settings</paragraph>
++<paragraph role="paragraph" id="par_id3149562" xml-lang="en-US" l10n="U">Specifies more comparison settings if the chosen mode is not Auto.</paragraph>
++<bookmark xml-lang="en-US" branch="hid/SW:CHECKBOX:TP_COMPARISON_OPT:CB_RSID" id="bm_id3161831" localize="false"/>
++<paragraph role="heading" id="hd_id3145785" xml-lang="en-US" level="3" l10n="U">Use RSID</paragraph>
++<paragraph role="paragraph" id="par_id3154638" xml-lang="en-US" l10n="U"><ahelp hid="SW:CHECKBOX:TP_COMPARISON_OPT:CB_RSID">Specifies that RSIDs are used when the documents are compared. This has an effect only if both documents have RSIDs and their root RSIDs are the same.</ahelp></paragraph>
++<bookmark xml-lang="en-US" branch="hid/SW:CHECKBOX:TP_COMPARISON_OPT:CB_IGNORE" id="bm_id3148618" localize="false"/>
++<paragraph role="heading" id="hd_id3163713" xml-lang="en-US" level="3" l10n="U">Ignore isolated pieces of length</paragraph>
++<paragraph role="paragraph" id="par_id3146975" xml-lang="en-US" l10n="U"><ahelp hid="SW:CHECKBOX:TP_COMPARISON_OPT:CB_IGNORE">Specifies that matched sequences of words or characters (depending on the chosen compare mode) of length equal to or less than the entered one will be ignored and will be shown as inserted/deleted.</ahelp></paragraph>
++</body>
++</helpdocument>
+diff --git helpcontent2/source/text/shared/optionen/makefile.mk helpcontent2/source/text/shared/optionen/makefile.mk
+index 88d6249..70be0bb 100644
+--- helpcontent2/source/text/shared/optionen/makefile.mk
++++ helpcontent2/source/text/shared/optionen/makefile.mk
+@@ -117,6 +117,7 @@ XHPFILES = \
+    01160100.xhp \
+    01160200.xhp \
+    01160201.xhp \
++   comparisonopt.xhp \
+    java.xhp \
+    javaclasspath.xhp \
+    javaparameters.xhp \
+@@ -130,7 +131,7 @@ XHPFILES = \
+    viewcertificate.xhp \
+    viewcertificate_c.xhp \
+    viewcertificate_d.xhp \
+-   viewcertificate_g.xhp 
++   viewcertificate_g.xhp
+     
+ # --- Targets ------------------------------------------------------
+ 
+diff --git helpcontent2/util/swriter/makefile.mk helpcontent2/util/swriter/makefile.mk
+index f550ef9..4750400 100644
+--- helpcontent2/util/swriter/makefile.mk
++++ helpcontent2/util/swriter/makefile.mk
+@@ -1318,6 +1318,7 @@ LINKLINKFILES= \
+    text$/shared$/optionen$/01160100.xhp \
+    text$/shared$/optionen$/01160200.xhp \
+    text$/shared$/optionen$/01160201.xhp \
++   text$/shared$/optionen$/comparisonopt.xhp \
+    text$/shared$/optionen$/java.xhp \
+    text$/shared$/optionen$/javaclasspath.xhp \
+    text$/shared$/optionen$/javaparameters.xhp \
+diff --git officecfg/registry/schema/org/openoffice/Office/Writer.xcs officecfg/registry/schema/org/openoffice/Office/Writer.xcs
+index 666a69f..bf953f0 100644
+--- officecfg/registry/schema/org/openoffice/Office/Writer.xcs
++++ officecfg/registry/schema/org/openoffice/Office/Writer.xcs
+@@ -2804,6 +2804,36 @@
+ 				</prop>
+ 			</group>
+ 		</group>
++		<group oor:name="Comparison">
++			<info>
++				<desc>Contains settings for comparing files.</desc>
++			</info>
++			<prop oor:name="Mode" oor:type="xs:short">
++				<info>
++					<author>OS</author>
++					<desc>Defines the Comparison Mode.</desc>
++				</info>
++			</prop>
++		
++			<prop oor:name="UseRSID" oor:type="xs:boolean">
++				<info>
++					<author>OS</author>
++					<desc>Specifies if RSIDs are used in comparison.</desc>
++				</info>
++			</prop>
++			<prop oor:name="IgnorePieces" oor:type="xs:boolean">
++				<info>
++					<author>OS</author>
++					<desc>Specifies if short pieces of matched text are ignored.</desc>
++				</info>
++			</prop>
++			<prop oor:name="IgnoreLength" oor:type="xs:short">
++				<info>
++					<author>OS</author>
++					<desc>Defines the length of ignored pieces.</desc>
++				</info>
++			</prop>
++		</group>
+ 		<group oor:name="Insert">
+ 			<info>
+ 				<desc>Specifies the settings for inserting various object types.</desc>
+diff --git svx/inc/svx/dialogs.hrc svx/inc/svx/dialogs.hrc
+index 53d5aae..04705b1 100644
+--- svx/inc/svx/dialogs.hrc
++++ svx/inc/svx/dialogs.hrc
+@@ -1555,6 +1555,7 @@
+ #define	RID_OFA_TP_INTERNATIONAL_IMPR	(RID_OFA_START + 254)		// 4 impress
+ #define RID_SW_TP_OPTCOMPATIBILITY_PAGE (RID_OFA_START + 255)
+ #define OFA_TP_LANGUAGES_FOR_SET_DOCUMENT_LANGUAGE      ( RID_OFA_START + 256 )
++#define RID_SW_TP_COMPARISON_OPT		(RID_OFA_START + 257)
+ 
+ //add for Dialog SchTransformTabDialog,SvxTransformTabDialog //CHINA001
+ #define RID_SCH_TransformTabDLG_SVXPAGE_ANGLE			(RID_SVX_START + 998)
+diff --git svx/inc/svx/rsiditem.hxx svx/inc/svx/rsiditem.hxx
+new file mode 100644
+index 0000000..53abf3d
+--- /dev/null
++++ svx/inc/svx/rsiditem.hxx
+@@ -0,0 +1,57 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ * 
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: rsiditem.hxx,v $
++ * $Revision: 1.0 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++ 
++#ifndef _SVX_RSIDITEM_HXX
++#define _SVX_RSIDITEM_HXX
++
++#include <svtools/intitem.hxx>
++#include <svx/svddef.hxx>
++#include "svx/svxdllapi.h"
++
++//----------------------
++// SvxRsidItem 
++//----------------------
++
++class SVX_DLLPUBLIC SvxRsidItem : public SfxUInt32Item
++{
++public:
++	TYPEINFO();
++
++	SvxRsidItem( UINT32 nRsid, USHORT nId ) : SfxUInt32Item( nId, nRsid ) {}
++	SvxRsidItem( SvStream& rIn, USHORT nId ) : SfxUInt32Item( nId, rIn ) {}
++
++	virtual SfxPoolItem* Clone( SfxItemPool* pPool = NULL ) const;
++	virtual SfxPoolItem* Create( SvStream& rIn, USHORT nVer ) const;
++
++	virtual sal_Bool QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const;
++	virtual sal_Bool PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 );
++};
++
++#endif // _SVX_RSIDITEM_HXX
+diff --git svx/inc/svx/svxenum.hxx svx/inc/svx/svxenum.hxx
+index ede33d5..9273451 100644
+--- svx/inc/svx/svxenum.hxx
++++ svx/inc/svx/svxenum.hxx
+@@ -260,5 +260,11 @@ enum SvxExtNumType
+     SVX_NUM_CHARS_LOWER_LETTER_N
+ };
+ 
++enum SvxCompareMode
++{
++	SVX_CMP_AUTO = 0,
++	SVX_CMP_BY_WORD,
++	SVX_CMP_BY_CHAR
++};
+ 
+ #endif
+diff --git svx/prj/d.lst svx/prj/d.lst
+index 5d34ef6..2fb31d7 100644
+--- svx/prj/d.lst
++++ svx/prj/d.lst
+@@ -337,6 +337,7 @@ mkdir: %_DEST%\inc%_EXT%\svx
+ ..\inc\svx\view3d.hxx %_DEST%\inc%_EXT%\svx\view3d.hxx
+ ..\inc\svx\viewpt3d.hxx %_DEST%\inc%_EXT%\svx\viewpt3d.hxx
+ ..\inc\svx\wghtitem.hxx %_DEST%\inc%_EXT%\svx\wghtitem.hxx
++..\inc\svx\rsiditem.hxx %_DEST%\inc%_EXT%\svx\rsiditem.hxx
+ ..\inc\svx\widwitem.hxx %_DEST%\inc%_EXT%\svx\widwitem.hxx
+ ..\inc\orienthelper.hxx %_DEST%\inc%_EXT%\svx\orienthelper.hxx
+ ..\inc\svx\wrlmitem.hxx %_DEST%\inc%_EXT%\svx\wrlmitem.hxx
+diff --git svx/source/dialog/treeopt.cxx svx/source/dialog/treeopt.cxx
+index 9af727e..4a099b1 100644
+--- svx/source/dialog/treeopt.cxx
++++ svx/source/dialog/treeopt.cxx
+@@ -438,6 +438,7 @@ static OptionsMapping_Impl __READONLY_DATA OptionsMap_Impl[] =
+     { "Writer",             "Print",                RID_SW_TP_OPTPRINT_PAGE },
+     { "Writer",             "Table",                RID_SW_TP_OPTTABLE_PAGE },
+     { "Writer",             "Changes",              RID_SW_TP_REDLINE_OPT },
++    { "Writer",             "Comparison",           RID_SW_TP_COMPARISON_OPT },
+     { "Writer",             "Compatibility",        RID_SW_TP_OPTCOMPATIBILITY_PAGE },
+     { "Writer",             "AutoCaption",          RID_SW_TP_OPTCAPTION_PAGE },
+     { "Writer",             "MailMerge",            RID_SW_TP_MAILCONFIG },
+diff --git svx/source/dialog/treeopt.src svx/source/dialog/treeopt.src
+index 9d4a19c..9abe6be 100644
+--- svx/source/dialog/treeopt.src
++++ svx/source/dialog/treeopt.src
+@@ -206,6 +206,7 @@ Resource RID_OFADLG_OPTIONS_TREE_PAGES
+             < "Print" ;       RID_SW_TP_OPTPRINT_PAGE  ; > ;
+             < "Table" ;  		RID_SW_TP_OPTTABLE_PAGE  ; > ;
+             < "Changes" ;    RID_SW_TP_REDLINE_OPT    ; > ;
++			< "Comparison" ; RID_SW_TP_COMPARISON_OPT ; > ;
+             < "Compatibility" ; RID_SW_TP_OPTCOMPATIBILITY_PAGE    ; > ;
+             < "AutoCaption" ; RID_SW_TP_OPTCAPTION_PAGE ; > ;
+             < "Mail Merge E-mail" ; RID_SW_TP_MAILCONFIG ; >;
+diff --git svx/source/items/textitem.cxx svx/source/items/textitem.cxx
+index 8460558..0b1f41b 100644
+--- svx/source/items/textitem.cxx
++++ svx/source/items/textitem.cxx
+@@ -81,7 +81,7 @@
+ #include <com/sun/star/i18n/ScriptType.hpp>
+ #include <svx/unomid.hxx>
+ 
+-
++#include <svx/rsiditem.hxx>
+ #include "flstitem.hxx"
+ #include "fontitem.hxx"
+ #include <svx/postitem.hxx>
+@@ -167,7 +167,7 @@ TYPEINIT1_FACTORY(SvxScriptTypeItem, SfxUInt16Item, new SvxScriptTypeItem);
+ TYPEINIT1_FACTORY(SvxCharRotateItem, SfxUInt16Item, new SvxCharRotateItem(0, sal_False, 0));
+ TYPEINIT1_FACTORY(SvxCharScaleWidthItem, SfxUInt16Item, new SvxCharScaleWidthItem(100, 0));
+ TYPEINIT1_FACTORY(SvxCharReliefItem, SfxEnumItem, new SvxCharReliefItem(RELIEF_NONE, 0));
+-
++TYPEINIT1_FACTORY(SvxRsidItem, SfxUInt32Item, new SvxRsidItem(0, 0));
+ 
+ TYPEINIT1(SvxScriptSetItem, SfxSetItem );
+ 
+@@ -3847,3 +3847,38 @@ short GetI18NScriptType( USHORT nItemType )
+     }
+     return 0;
+ }
++
++// class SvxRsidItem -----------------------------------------------------
++
++sal_Bool SvxRsidItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
++{
++	rVal <<= ( (UINT32)GetValue() );
++  	return sal_True;
++}
++
++// -----------------------------------------------------------------------
++
++sal_Bool SvxRsidItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
++{
++	UINT32 nRsid = 0;
++	if( !( rVal >>= nRsid ) )
++		return sal_False;
++
++	SetValue( nRsid );
++	return sal_True;
++}
++
++// -----------------------------------------------------------------------
++
++SfxPoolItem* SvxRsidItem::Clone( SfxItemPool * ) const
++{
++	return new SvxRsidItem( *this );
++}
++
++// -----------------------------------------------------------------------
++
++SfxPoolItem* SvxRsidItem::Create(SvStream& rIn, USHORT nVer) const
++{
++	return new SvxRsidItem( rIn, Which() );
++}
++
+diff --git sw/inc/cmdid.h sw/inc/cmdid.h
+index d2df79f..d1ed2c6 100644
+--- sw/inc/cmdid.h
++++ sw/inc/cmdid.h
+@@ -1196,7 +1196,6 @@ Achtung: Ab sofort sind in diesem File keine C++-Kommentare (//) mehr
+ // --> OD 2004-10-28 #i36248#
+ #define FN_SHAPE_STARTPOSITION_IN_HORI_L2R (FN_PARAM2+25)
+ #define FN_SHAPE_ENDPOSITION_IN_HORI_L2R   (FN_PARAM2+26)
+-
+ // <--
+ /*--------------------------------------------------------------------
+     Bereich: Druckoptionen
+diff --git sw/inc/doc.hxx sw/inc/doc.hxx
+index 8507a8c..82f49d8 100644
+--- sw/inc/doc.hxx
++++ sw/inc/doc.hxx
+@@ -448,6 +448,9 @@ private:
+     RedlineMode_t eRedlineMode;		// aktueller Redline Modus
+     SwCharCompressType eChrCmprType;	// for ASIAN: compress punctuation/kana
+ 
++	sal_uInt32  nRsid;				// current session ID of the document
++	sal_uInt32  nRsidRoot;			// session ID when the document was created 
++
+     sal_Int32   mReferenceCount;
+     sal_Int32   mIdleBlockCount;
+     sal_Int8	nLockExpFld;		// Wenn != 0 hat UpdateExpFlds() keine Wirkung
+@@ -757,6 +760,10 @@ public:
+     virtual void setFieldUpdateFlags( /*[in]*/ SwFldUpdateFlags eMode );
+     virtual SwCharCompressType getCharacterCompressionType() const;
+     virtual void setCharacterCompressionType( /*[in]*/SwCharCompressType nType );
++    virtual sal_uInt32 getRsid() const;
++	virtual void setRsid( sal_uInt32 nVal );
++	virtual sal_uInt32 getRsidRoot() const;
++	virtual void setRsidRoot( sal_uInt32 nVal );
+     SwBookmark* getFieldBookmarkFor(const SwPosition &pos) const;
+     SwBookmark* getNextFieldBookmarkFor(const SwPosition &pos) const;
+     SwBookmark* getPrevFieldBookmarkFor(const SwPosition &pos) const;
+@@ -937,6 +944,9 @@ public:
+     virtual bool Overwrite(const SwPaM &rRg, const String& rStr);
+     virtual bool Insert(const SwPaM &rRg, sal_Unicode c);
+     virtual bool Insert(const SwPaM &rRg, const String&, bool bHintExpand);
++	virtual bool UpdateRsid( SwTxtNode *pTxtNode, xub_StrLen nStt, xub_StrLen nEnd );
++	virtual bool UpdateParRsid( SwTxtNode *pTxtNode, UINT32 nVal = 0 );
++	virtual bool UpdateRsid( const SwPaM &rRg, xub_StrLen nLen );
+     virtual SwFlyFrmFmt* Insert(const SwPaM &rRg, const String& rGrfName, const String& rFltName, const Graphic* pGraphic,
+                         const SfxItemSet* pFlyAttrSet, const SfxItemSet* pGrfAttrSet, SwFrmFmt*);
+     virtual SwFlyFrmFmt* Insert(const SwPaM& rRg, const GraphicObject& rGrfObj,	const SfxItemSet* pFlyAttrSet,
+diff --git sw/inc/globals.hrc sw/inc/globals.hrc
+index 2216249..c8dedcd 100644
+--- sw/inc/globals.hrc
++++ sw/inc/globals.hrc
+@@ -277,6 +277,7 @@
+ #define TP_SECTION_INDENTS          (RC_GLOBALS_BEGIN +  102)
+ #define TP_OPTCOMPATIBILITY_PAGE	(RC_GLOBALS_BEGIN +  103)
+ #define TP_MAILCONFIG               (RC_GLOBALS_BEGIN +  104)
++#define TP_COMPARISON_OPT           (RC_GLOBALS_BEGIN +  105)
+ //maximum: RC_GLOBALS_BEGIN +  119
+ 
+ #if STR_DOC_STAT > RC_GLOBALS_END
+diff --git sw/inc/helpid.h sw/inc/helpid.h
+index 3172447..b4afd73 100644
+--- sw/inc/helpid.h
++++ sw/inc/helpid.h
+@@ -313,6 +313,7 @@
+ #define HID_TEXTGRID_PAGE				(HID_BASE + 482)
+ #define HID_OPTCOMPATIBILITY_PAGE		(HID_BASE + 483)
+ #define HID_COMPATIBILITY_OPTIONS_BOX	(HID_BASE + 484)
++#define HID_COMPARISON_OPT				(HID_BASE + 485)
+ 
+ // AutoPilot Help-IDs *********************************************************
+ 
+diff --git sw/inc/hintids.hxx sw/inc/hintids.hxx
+index faad379..d0e9b35 100644
+--- sw/inc/hintids.hxx
++++ sw/inc/hintids.hxx
+@@ -98,8 +98,8 @@ RES_CHRATR_BEGIN = HINT_BEGIN,
+     RES_CHRATR_RELIEF,						// 36
+     RES_CHRATR_HIDDEN,                      // 37
+     RES_CHRATR_OVERLINE,					// 38
+-    RES_CHRATR_DUMMY1,						// 39
+-    RES_CHRATR_DUMMY2,						// 40
++	RES_CHRATR_RSID,						// 39
++	RES_CHRATR_DUMMY1,						// 40
+ RES_CHRATR_END
+ };
+ 
+@@ -160,6 +160,7 @@ RES_PARATR_BEGIN = RES_TXTATR_END,
+     RES_PARATR_SNAPTOGRID,                          // 72
+     RES_PARATR_CONNECT_BORDER,                      // 73
+     RES_PARATR_OUTLINELEVEL,                        // 74
++    RES_PARATR_RSID,								// 75
+ RES_PARATR_END
+ };
+ 
+@@ -169,11 +170,11 @@ RES_PARATR_END
+ enum RES_PARATR_LIST
+ {
+ RES_PARATR_LIST_BEGIN = RES_PARATR_END,
+-    RES_PARATR_LIST_ID = RES_PARATR_LIST_BEGIN,     // 75
+-    RES_PARATR_LIST_LEVEL,                          // 76
+-    RES_PARATR_LIST_ISRESTART,                      // 77
+-    RES_PARATR_LIST_RESTARTVALUE,                   // 78
+-    RES_PARATR_LIST_ISCOUNTED,                      // 79
++    RES_PARATR_LIST_ID = RES_PARATR_LIST_BEGIN,     // 76
++    RES_PARATR_LIST_LEVEL,                          // 77
++    RES_PARATR_LIST_ISRESTART,                      // 78
++    RES_PARATR_LIST_RESTARTVALUE,                   // 79
++    RES_PARATR_LIST_ISCOUNTED,                      // 80
+ RES_PARATR_LIST_END
+ };
+ // <--
+@@ -181,92 +182,92 @@ RES_PARATR_LIST_END
+ enum RES_FRMATR
+ {
+ RES_FRMATR_BEGIN = RES_PARATR_LIST_END,
+-    RES_FILL_ORDER = RES_FRMATR_BEGIN,              // 80
+-    RES_FRM_SIZE,                                   // 81
+-    RES_PAPER_BIN,                                  // 82
+-    RES_LR_SPACE,                                   // 83
+-    RES_UL_SPACE,                                   // 84
+-    RES_PAGEDESC,                                   // 85
+-    RES_BREAK,                                      // 86
+-    RES_CNTNT,                                      // 87
+-    RES_HEADER,                                     // 88
+-    RES_FOOTER,                                     // 89
+-    RES_PRINT,                                      // 90
+-    RES_OPAQUE,                                     // 91
+-    RES_PROTECT,                                    // 92
+-    RES_SURROUND,                                   // 93
+-    RES_VERT_ORIENT,                                // 94
+-    RES_HORI_ORIENT,                                // 95
+-    RES_ANCHOR,                                     // 96
+-    RES_BACKGROUND,                                 // 97
+-    RES_BOX,                                        // 98
+-    RES_SHADOW,                                     // 99
+-    RES_FRMMACRO,                                   // 100
+-    RES_COL,                                        // 101
+-    RES_KEEP,                                       // 102
+-    RES_URL,                                        // 103
+-    RES_EDIT_IN_READONLY,                           // 104
+-    RES_LAYOUT_SPLIT,                               // 105
+-    RES_CHAIN,                                      // 106
+-    RES_TEXTGRID,                                   // 107
+-    RES_LINENUMBER  ,                               // 108
+-    RES_FTN_AT_TXTEND,                              // 109
+-    RES_END_AT_TXTEND,                              // 110
+-    RES_COLUMNBALANCE,                              // 111
+-    RES_FRAMEDIR,                                   // 112
+-    RES_HEADER_FOOTER_EAT_SPACING,                  // 113
+-    RES_ROW_SPLIT,                                  // 114
++    RES_FILL_ORDER = RES_FRMATR_BEGIN,              // 81
++    RES_FRM_SIZE,                                   // 82
++    RES_PAPER_BIN,                                  // 83
++    RES_LR_SPACE,                                   // 84
++    RES_UL_SPACE,                                   // 85
++    RES_PAGEDESC,                                   // 86
++    RES_BREAK,                                      // 87
++    RES_CNTNT,                                      // 88
++    RES_HEADER,                                     // 89
++    RES_FOOTER,                                     // 90
++    RES_PRINT,                                      // 91
++    RES_OPAQUE,                                     // 92
++    RES_PROTECT,                                    // 93
++    RES_SURROUND,                                   // 94
++    RES_VERT_ORIENT,                                // 95
++    RES_HORI_ORIENT,                                // 96
++    RES_ANCHOR,                                     // 97
++    RES_BACKGROUND,                                 // 98
++    RES_BOX,                                        // 99
++    RES_SHADOW,                                     // 100
++    RES_FRMMACRO,                                   // 101
++    RES_COL,                                        // 102
++    RES_KEEP,                                       // 103
++    RES_URL,                                        // 104
++    RES_EDIT_IN_READONLY,                           // 105
++    RES_LAYOUT_SPLIT,                               // 106
++    RES_CHAIN,                                      // 107
++    RES_TEXTGRID,                                   // 108
++    RES_LINENUMBER  ,                               // 109
++    RES_FTN_AT_TXTEND,                              // 110
++    RES_END_AT_TXTEND,                              // 111
++    RES_COLUMNBALANCE,                              // 112
++    RES_FRAMEDIR,                                   // 113
++    RES_HEADER_FOOTER_EAT_SPACING,                  // 114
++    RES_ROW_SPLIT,                                  // 115
+     // OD 18.09.2003 #i18732# - insert new item and 5 dummies
+-    RES_FOLLOW_TEXT_FLOW,                           // 115
++    RES_FOLLOW_TEXT_FLOW,                           // 116
+ // --> collapsing borders FME 2005-05-27 #i29550#
+-    RES_COLLAPSING_BORDERS,                         // 116
++    RES_COLLAPSING_BORDERS,                         // 117
+ // <-- collapsing
+     // OD 2004-05-04 #i28701# - use dummy1 for new item
+-    RES_WRAP_INFLUENCE_ON_OBJPOS,                   // 117
+-    RES_AUTO_STYLE,                                 // 118
+-    RES_FRMATR_STYLE_NAME,                          // 119
+-    RES_FRMATR_CONDITIONAL_STYLE_NAME,              // 120
++    RES_WRAP_INFLUENCE_ON_OBJPOS,                   // 118
++    RES_AUTO_STYLE,                                 // 119
++    RES_FRMATR_STYLE_NAME,                          // 120
++    RES_FRMATR_CONDITIONAL_STYLE_NAME,              // 121
+ RES_FRMATR_END
+ };
+ 
+ enum RES_GRFATR
+ {
+ RES_GRFATR_BEGIN = RES_FRMATR_END,
+-    RES_GRFATR_MIRRORGRF = RES_GRFATR_BEGIN,        // 121
+-    RES_GRFATR_CROPGRF,                             // 122
+-
+-    RES_GRFATR_ROTATION,                            // 123
+-    RES_GRFATR_LUMINANCE,                           // 124
+-    RES_GRFATR_CONTRAST,                            // 125
+-    RES_GRFATR_CHANNELR,                            // 126
+-    RES_GRFATR_CHANNELG,                            // 127
+-    RES_GRFATR_CHANNELB,                            // 128
+-    RES_GRFATR_GAMMA,                               // 129
+-    RES_GRFATR_INVERT,                              // 130
+-    RES_GRFATR_TRANSPARENCY,                        // 131
+-    RES_GRFATR_DRAWMODE,                            // 132
+-
+-    RES_GRFATR_DUMMY1,                              // 133
+-    RES_GRFATR_DUMMY2,                              // 134
+-    RES_GRFATR_DUMMY3,                              // 135
+-    RES_GRFATR_DUMMY4,                              // 136
+-    RES_GRFATR_DUMMY5,                              // 137
++    RES_GRFATR_MIRRORGRF = RES_GRFATR_BEGIN,        // 122
++    RES_GRFATR_CROPGRF,                             // 123
++
++    RES_GRFATR_ROTATION,                            // 124
++    RES_GRFATR_LUMINANCE,                           // 125
++    RES_GRFATR_CONTRAST,                            // 126
++    RES_GRFATR_CHANNELR,                            // 127
++    RES_GRFATR_CHANNELG,                            // 128
++    RES_GRFATR_CHANNELB,                            // 129
++    RES_GRFATR_GAMMA,                               // 130
++    RES_GRFATR_INVERT,                              // 131
++    RES_GRFATR_TRANSPARENCY,                        // 132
++    RES_GRFATR_DRAWMODE,                            // 133
++
++    RES_GRFATR_DUMMY1,                              // 134
++    RES_GRFATR_DUMMY2,                              // 135
++    RES_GRFATR_DUMMY3,                              // 136
++    RES_GRFATR_DUMMY4,                              // 137
++    RES_GRFATR_DUMMY5,                              // 138
+ RES_GRFATR_END
+ };
+ 
+ enum RES_BOXATR
+ {
+ RES_BOXATR_BEGIN = RES_GRFATR_END,
+-    RES_BOXATR_FORMAT = RES_BOXATR_BEGIN,           // 138
+-    RES_BOXATR_FORMULA,                             // 139
+-    RES_BOXATR_VALUE,                               // 140
++    RES_BOXATR_FORMAT = RES_BOXATR_BEGIN,           // 139
++    RES_BOXATR_FORMULA,                             // 140
++    RES_BOXATR_VALUE,                               // 141
+ RES_BOXATR_END
+ };
+ 
+ enum RES_UNKNOWNATR
+ {
+ RES_UNKNOWNATR_BEGIN = RES_BOXATR_END,
+-    RES_UNKNOWNATR_CONTAINER = RES_UNKNOWNATR_BEGIN,// 141
++    RES_UNKNOWNATR_CONTAINER = RES_UNKNOWNATR_BEGIN,// 142
+ RES_UNKNOWNATR_END
+ };
+ 
+diff --git sw/inc/modcfg.hxx sw/inc/modcfg.hxx
+index 8b5b1c7..c92520f 100644
+--- sw/inc/modcfg.hxx
++++ sw/inc/modcfg.hxx
+@@ -41,6 +41,7 @@
+ #include "tblenum.hxx"
+ #include "itabenum.hxx"
+ #include <tools/globname.hxx>
++#include <svx/svxenum.hxx>
+ class SwModuleOptions;
+ 
+ //-----------------------------------------------------------------------------
+@@ -166,7 +167,27 @@ class SwMiscConfig : public utl::ConfigItem
+     void					Load();
+     void 					SetModified(){ConfigItem::SetModified();}
+ };
++/* ---------------------------------------------------------------------------
+ 
++ ---------------------------------------------------------------------------*/
++class SwCompareConfig : public utl::ConfigItem
++{
++	friend class SwModuleOptions;
++	
++	USHORT	   eCmpMode;		//Compare/CompareDocuments;
++	sal_Bool		bUseRsid;		//Compare/Settings/Use RSID
++	sal_Bool		bIgnorePieces;	//Compare/Settings/Ignore pieces of length
++	USHORT		nPieceLen;		//Compare/Settings/Ignore pieces of length
++
++	const com::sun::star::uno::Sequence<rtl::OUString>& GetPropertyNames();
++	public:
++		SwCompareConfig();
++		~SwCompareConfig();
++
++	virtual void			Commit();
++	void					Load();
++	void 					SetModified() {ConfigItem::SetModified(); }
++};
+ /* ---------------------------------------------------------------------------
+ 
+  ---------------------------------------------------------------------------*/
+@@ -180,6 +201,8 @@ class SW_DLLPUBLIC SwModuleOptions
+     SwTableConfig					aWebTableConfig;
+ 
+     SwMiscConfig					aMiscConfig;
++	
++	SwCompareConfig					aCompareConfig;
+ 
+     //fiscus: don't show tips of text fields - it's not part of the configuration!
+     BOOL 		bHideFieldTips : 1;
+@@ -337,6 +360,24 @@ public:
+ 
+     BOOL 		IsHideFieldTips() const {return bHideFieldTips;}
+     void		SetHideFieldTips(BOOL bSet) {bHideFieldTips = bSet;}
++	
++	SvxCompareMode	GetCompareMode() const				{ return (SvxCompareMode)aCompareConfig.eCmpMode; }
++	void			SetCompareMode( SvxCompareMode eMode )		{ aCompareConfig.eCmpMode = eMode; 
++															aCompareConfig.SetModified(); }
++
++	BOOL			IsUseRsid() const					{ return aCompareConfig.bUseRsid; }
++	void			SetUseRsid( BOOL b )					{ aCompareConfig.bUseRsid = b; 
++															aCompareConfig.SetModified(); }
++
++	BOOL			IsIgnorePieces() const				{ return aCompareConfig.bIgnorePieces; }
++	void			SetIgnorePieces( BOOL b )			{ aCompareConfig.bIgnorePieces = b; 
++															aCompareConfig.SetModified(); }
++
++	USHORT			GetPieceLen() const					{ return aCompareConfig.nPieceLen; }
++	void			SetPieceLen( USHORT nLen )			{ aCompareConfig.nPieceLen = nLen; 
++															aCompareConfig.SetModified(); }
++																			
++	
+ };
+ #endif
+ 
+diff --git sw/inc/ndtxt.hxx sw/inc/ndtxt.hxx
+index cf282c3..1341be1 100644
+--- sw/inc/ndtxt.hxx
++++ sw/inc/ndtxt.hxx
+@@ -808,6 +808,13 @@ public:
+ 
+     USHORT GetScalingOfSelectedText( xub_StrLen nStt, xub_StrLen nEnd ) const;
+ 
++	UINT32 GetRsid( xub_StrLen nStt, xub_StrLen nEnd ) const;
++	UINT32 GetParRsid() const;
++	
++	bool CompareRsid( const SwTxtNode &rTxtNode, xub_StrLen nStt1, xub_StrLen nStt2, 
++			xub_StrLen nEnd1 = 0,  xub_StrLen nEnd2 = 0 ) const;
++	bool CompareParRsid( const SwTxtNode &rTxtNode ) const;
++
+     DECL_FIXEDMEMPOOL_NEWDEL(SwTxtNode)
+ };
+ 
+diff --git sw/inc/swmodule.hxx sw/inc/swmodule.hxx
+index bdf5e54..76956af 100644
+--- sw/inc/swmodule.hxx
++++ sw/inc/swmodule.hxx
+@@ -42,6 +42,7 @@
+ #include <fldupde.hxx>
+ #include <com/sun/star/linguistic2/XLinguServiceEventListener.hpp>
+ #include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
++#include <svx/svxenum.hxx>
+ 
+ class SvStringsDtor;
+ class Color;
+@@ -212,6 +213,15 @@ public:
+     sal_uInt16				GetRedlineMarkPos();
+     const Color&			GetRedlineMarkColor();
+ 
++	SvxCompareMode		GetCompareMode() const;
++	void				SetCompareMode( SvxCompareMode eMode );
++	BOOL				IsUseRsid() const;
++	void				SetUseRsid( BOOL b );
++	BOOL				IsIgnorePieces() const;
++	void				SetIgnorePieces( BOOL b );
++	USHORT				GetPieceLen() const;
++	void				SetPieceLen( USHORT nLen );
++
+     // returne den definierten DocStat - WordDelimiter
+     const String&		GetDocStatWordDelim() const;
+ 
+diff --git sw/inc/txatbase.hxx sw/inc/txatbase.hxx
+index 04b51ea..27b9526 100644
+--- sw/inc/txatbase.hxx
++++ sw/inc/txatbase.hxx
+@@ -39,6 +39,7 @@ class SvxBrushItem;
+ class SvxFontItem;
+ class SvxPostureItem;
+ class SvxWeightItem;
++class SvxRsidItem;
+ class SvxUnderlineItem;
+ class SvxOverlineItem;
+ class SvxFontHeightItem;
+@@ -169,6 +170,7 @@ public:
+     inline const SvxCharRotateItem		&GetCharRotate() const;
+     inline const SvxCharReliefItem      &GetCharRelief() const;
+     inline const SvxCharHiddenItem      &GetCharHidden() const;
++	inline const SvxRsidItem			&GetRsid() const;
+ 
+ private:
+     SwTxtAttr( const SwTxtAttr& );
+@@ -447,4 +449,9 @@ inline const SvxCharHiddenItem& SwTxtAttr::GetCharHidden() const
+     return (const SvxCharHiddenItem&)*pAttr;
+ }
+ 
++inline const SvxRsidItem& SwTxtAttr::GetRsid() const
++{
++	ASSERT( pAttr && pAttr->Which() == RES_CHRATR_RSID, "Wrong Request" );
++	return ( const SvxRsidItem& ) * pAttr;
++}
+ #endif
+diff --git sw/inc/undobj.hxx sw/inc/undobj.hxx
+index c1a3055..5fc1aff 100644
+--- sw/inc/undobj.hxx
++++ sw/inc/undobj.hxx
+@@ -506,6 +506,7 @@ class SwUndoSplitNode: public SwUndo
+     xub_StrLen nCntnt;
+     BOOL bTblFlag : 1;
+     BOOL bChkTblStt : 1;
++	UINT32 nParRsid;
+ public:
+     SwUndoSplitNode( SwDoc* pDoc, const SwPosition& rPos, BOOL bChkTbl );
+     virtual ~SwUndoSplitNode();
+diff --git sw/inc/unoprnms.hxx sw/inc/unoprnms.hxx
+index 558facb..49d9494 100644
+--- sw/inc/unoprnms.hxx
++++ sw/inc/unoprnms.hxx
+@@ -806,7 +806,9 @@ enum SwPropNameIds
+ /* 0736 */  UNO_NAME_OUTLINE_LEVEL,  //#outline level,add<-zhaojianwei outlinelevel
+ /* 0737 */  UNO_NAME_IS_TEMPLATE,
+ /* 0738 */  UNO_NAME_VBA_DOCOBJ,
+-/* 0739 */  SW_PROPNAME_END
++/* 0739 */  UNO_NAME_RSID,
++/* 0740 */  UNO_NAME_PARRSID,
++/* 0741 */  SW_PROPNAME_END
+ };
+ 
+ 
+diff --git sw/source/core/bastyp/init.cxx sw/source/core/bastyp/init.cxx
+index ca1a599..ab43b69 100644
+--- sw/source/core/bastyp/init.cxx
++++ sw/source/core/bastyp/init.cxx
+@@ -149,6 +149,7 @@
+ #include <fmtfollowtextflow.hxx>
+ // OD 2004-05-05 #i28701#
+ #include <fmtwrapinfluenceonobjpos.hxx>
++#include <svx/rsiditem.hxx>
+ 
+ using namespace ::com::sun::star;
+ 
+@@ -316,8 +317,8 @@ SfxItemInfo __FAR_DATA aSlotTab[] =
+     { SID_ATTR_CHAR_RELIEF, SFX_ITEM_POOLABLE },		// RES_CHRATR_RELIEF
+     { SID_ATTR_CHAR_HIDDEN, SFX_ITEM_POOLABLE },        // RES_CHRATR_HIDDEN
+     { SID_ATTR_CHAR_OVERLINE, SFX_ITEM_POOLABLE },  	// RES_CHRATR_OVERLINE
++	{ 0, SFX_ITEM_POOLABLE },							// RES_CHRATR_RSID
+     { 0, SFX_ITEM_POOLABLE },							// RES_CHRATR_DUMMY1
+-    { 0, SFX_ITEM_POOLABLE },							// RES_CHRATR_DUMMY2
+ 
+     { 0, SFX_ITEM_POOLABLE },                           // RES_TXTATR_AUTOFMT
+     { FN_TXTATR_INET, 0 },                              // RES_TXTATR_INETFMT
+@@ -360,7 +361,7 @@ SfxItemInfo __FAR_DATA aSlotTab[] =
+     { SID_ATTR_BORDER_CONNECT, SFX_ITEM_POOLABLE },     // RES_PARATR_CONNECT_BORDER
+ 
+     { SID_ATTR_PARA_OUTLINE_LEVEL, SFX_ITEM_POOLABLE }, // RES_PARATR_OUTLINELEVEL //#outline level,zhaojianwei
+-
++	{ 0, SFX_ITEM_POOLABLE },							// RES_PARATR_RSID
+     // --> OD 2008-02-19 #refactorlists#
+     { 0, SFX_ITEM_POOLABLE },                           // RES_PARATR_LIST_ID
+     { 0, SFX_ITEM_POOLABLE },                           // RES_PARATR_LIST_LEVEL
+@@ -499,6 +500,7 @@ void _InitCore()
+     aAttrTab[ RES_CHRATR_SHADOWED- POOLATTR_BEGIN ] =       new SvxShadowedItem( sal_False, RES_CHRATR_SHADOWED );
+     aAttrTab[ RES_CHRATR_UNDERLINE- POOLATTR_BEGIN ] =      new SvxUnderlineItem( UNDERLINE_NONE, RES_CHRATR_UNDERLINE );
+     aAttrTab[ RES_CHRATR_WEIGHT- POOLATTR_BEGIN ] =         new SvxWeightItem( WEIGHT_NORMAL, RES_CHRATR_WEIGHT );
++    aAttrTab[ RES_CHRATR_RSID - POOLATTR_BEGIN ] =          new SvxRsidItem( 0, RES_CHRATR_RSID );
+     aAttrTab[ RES_CHRATR_WORDLINEMODE- POOLATTR_BEGIN ] =   new SvxWordLineModeItem( sal_False, RES_CHRATR_WORDLINEMODE );
+     aAttrTab[ RES_CHRATR_AUTOKERN- POOLATTR_BEGIN ] =       new SvxAutoKernItem( sal_False, RES_CHRATR_AUTOKERN );
+     aAttrTab[ RES_CHRATR_BLINK - POOLATTR_BEGIN ] =         new SvxBlinkItem( FALSE, RES_CHRATR_BLINK );
+@@ -530,7 +532,7 @@ void _InitCore()
+ 
+ // CharakterAttr - Dummies
+     aAttrTab[ RES_CHRATR_DUMMY1 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_CHRATR_DUMMY1 );
+-    aAttrTab[ RES_CHRATR_DUMMY2 - POOLATTR_BEGIN ] = new SfxBoolItem( RES_CHRATR_DUMMY2 );
++
+ // CharakterAttr - Dummies
+ 
+     aAttrTab[ RES_TXTATR_AUTOFMT- POOLATTR_BEGIN ] = new SwFmtAutoFmt;
+@@ -578,7 +580,8 @@ void _InitCore()
+     aAttrTab[ RES_PARATR_CONNECT_BORDER - POOLATTR_BEGIN ] = new SwParaConnectBorderItem;
+ 
+     aAttrTab[ RES_PARATR_OUTLINELEVEL - POOLATTR_BEGIN ] = new SfxUInt16Item( RES_PARATR_OUTLINELEVEL, 0 );//#outline level,zhaojianwei
+-
++	aAttrTab[ RES_PARATR_RSID - POOLATTR_BEGIN ] = new SvxRsidItem( 0, RES_PARATR_RSID );
++	
+     // --> OD 2008-02-19 #refactorlists#
+     aAttrTab[ RES_PARATR_LIST_ID - POOLATTR_BEGIN ] = new SfxStringItem( RES_PARATR_LIST_ID, aEmptyStr );
+     aAttrTab[ RES_PARATR_LIST_LEVEL - POOLATTR_BEGIN ] = new SfxInt16Item( RES_PARATR_LIST_LEVEL, 0 );
+diff --git sw/source/core/doc/doc.cxx sw/source/core/doc/doc.cxx
+index f5ec3e5..38d08e8 100644
+--- sw/source/core/doc/doc.cxx
++++ sw/source/core/doc/doc.cxx
+@@ -35,6 +35,7 @@
+ 
+ #include <tools/shl.hxx>
+ #include <tools/globname.hxx>
++#include <rtl/random.h>
+ 
+ #include <com/sun/star/i18n/WordType.hdl>
+ #include <com/sun/star/i18n/ForbiddenCharacters.hdl>
+@@ -55,6 +56,7 @@
+ #include <svx/linkmgr.hxx>
+ #include <svx/forbiddencharacterstable.hxx>
+ #include <svx/svdmodel.hxx>
++#include <svx/rsiditem.hxx>
+ #include <unotools/charclass.hxx>
+ #include <swmodule.hxx>
+ #include <fmtpdsc.hxx>
+@@ -410,6 +412,33 @@ void SwDoc::setLinkUpdateMode( /*[in]*/sal_uInt16 eMode )
+     nLinkUpdMode = eMode;
+ }
+ 
++sal_uInt32 SwDoc::getRsid() const
++{
++	return nRsid;
++}
++
++void SwDoc::setRsid( sal_uInt32 nVal )
++{
++	// Increase the rsid with a random number smaller than 2^17. This way we
++	// expect to be able to edit a document 2^12 times before rsid overflows.
++	sal_uInt32 nIncrease = 0;
++	static rtlRandomPool aPool = rtl_random_createPool();
++	rtl_random_getBytes( aPool, &nIncrease, sizeof ( nIncrease ) );
++	nIncrease &= ( 1<<17 ) - 1;
++	nIncrease++; // make sure the new rsid is not the same
++	nRsid = nVal + nIncrease;
++}
++
++sal_uInt32 SwDoc::getRsidRoot() const
++{
++	return nRsidRoot;
++}
++
++void SwDoc::setRsidRoot( sal_uInt32 nVal )
++{
++	nRsidRoot = nVal;
++}
++
+ SwFldUpdateFlags SwDoc::getFieldUpdateFlags( /*[in]*/bool bGlobalSettings ) const
+ {
+     SwFldUpdateFlags eRet = eFldUpdMode;
+@@ -650,6 +679,15 @@ bool SwDoc::SplitNode( const SwPosition &rPos, bool bChkTableStart )
+             AppendUndo( pUndo = new SwUndoSplitNode( this, rPos, bChkTableStart  ));
+     }
+ 
++	// Update the rsid of the old and the new node unless 
++	// the old node is split at the beginning or at the end
++	SwTxtNode *pTxtNode =  rPos.nNode.GetNode().GetTxtNode();
++	xub_StrLen nPos = rPos.nContent.GetIndex();
++	if( pTxtNode && nPos && nPos != pTxtNode->Len() )
++	{
++		UpdateParRsid( pTxtNode );
++	}
++	
+     //JP 28.01.97: Sonderfall fuer SplitNode am Tabellenanfang:
+     //				steht die am Doc/Fly/Footer/..-Anfang oder direkt
+     //				hinter einer Tabelle, dann fuege davor
+@@ -970,6 +1008,41 @@ SwFlyFrmFmt* SwDoc::InsertOLE(const SwPaM &rRg, const String& rObjName,
+                             pFrmFmt );
+ }
+ 
++// Set the rsid from nStt to nEnd of pTxtNode to the current session number
++bool SwDoc::UpdateRsid( SwTxtNode *pTxtNode, xub_StrLen nStt, xub_StrLen nEnd )
++{
++	if ( !pTxtNode )
++	{
++		return false;
++	}
++
++	SvxRsidItem aRsid( nRsid, RES_CHRATR_RSID );
++	SwTxtAttr* pAttr = pTxtNode->MakeTxtAttr( aRsid, nStt, nEnd );
++	return pTxtNode->Insert( pAttr, INS_DEFAULT );
++}
++
++// Set the rsid of the next nLen symbols of rRg to the current session number
++bool SwDoc::UpdateRsid( const SwPaM &rRg, const xub_StrLen nLen )
++{
++	const SwPosition* pPos = rRg.GetPoint();
++	SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
++	xub_StrLen nInsPos = pPos->nContent.GetIndex();
++	
++	return UpdateRsid( pTxtNode, nInsPos - nLen, nInsPos );
++}
++
++bool SwDoc::UpdateParRsid( SwTxtNode *pTxtNode, UINT32 nVal )
++{
++	if ( !pTxtNode )
++	{
++		return false;
++	}
++
++	SvxRsidItem aRsid( nVal ? nVal : nRsid, RES_PARATR_RSID );
++	return pTxtNode->SetAttr( aRsid );
++}
++
++
+ /*************************************************************************
+ |*				  SwDoc::GetFldType()
+ |*	  Beschreibung: liefert den am Doc eingerichteten Feldtypen zurueck
+diff --git sw/source/core/doc/doccomp.cxx sw/source/core/doc/doccomp.cxx
+index 05d6209..8f7521f 100644
+--- sw/source/core/doc/doccomp.cxx
++++ sw/source/core/doc/doccomp.cxx
+@@ -38,7 +38,9 @@
+ #include <svx/crsditem.hxx>
+ #include <svx/colritem.hxx>
+ #include <svx/boxitem.hxx>
++#include <svx/svxenum.hxx>
+ #include <svx/udlnitem.hxx>
++#include <swmodule.hxx>
+ #include <doc.hxx>
+ #include <docary.hxx>
+ #include <pam.hxx>
+@@ -52,6 +54,9 @@
+ #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+ #include <com/sun/star/document/XDocumentProperties.hpp>
+ 
++#include <set>
++#include <cctype>
++
+ using namespace ::com::sun::star;
+ 
+ 
+@@ -197,6 +202,149 @@ public:
+     Compare( ULONG nDiff, CompareData& rData1, CompareData& rData2 );
+ };
+ 
++//----------------------------------------------------------------
++
++class ArrayComparator
++{
++public:
++	virtual bool Compare( int nIdx1, int nIdx2 ) const = 0;
++	virtual int GetLen1() const = 0;
++	virtual int GetLen2() const = 0;
++};
++
++// Consider two lines equal if similar enough (e.g. look like different
++// versions of the same paragraph)
++class LineArrayComparator : public ArrayComparator
++{
++private:
++	int nLen1, nLen2;
++	const CompareData &rData1, &rData2;	
++	int nFirst1, nFirst2;
++
++public:
++	LineArrayComparator( const CompareData &rD1, const CompareData &rD2, 
++							int nStt1, int nEnd1, int nStt2, int nEnd2 );
++	
++	virtual bool Compare( int nIdx1, int nIdx2 ) const;
++	virtual int GetLen1() const { return nLen1; }
++	virtual int GetLen2() const { return nLen2; }
++};
++
++class WordArrayComparator : public ArrayComparator
++{
++private:
++	const SwTxtNode *pTxtNd1, *pTxtNd2;
++	int *pPos1, *pPos2;
++	int nCnt1, nCnt2;		// number of words
++	const unsigned nMul;
++	
++	void CalcPositions( int *pPos, const SwTxtNode *pTxtNd, int &nCnt );
++
++public:
++	WordArrayComparator( const SwTxtNode *pNode1, const SwTxtNode *pNode2 );	
++	~WordArrayComparator();
++	
++	virtual bool Compare( int nIdx1, int nIdx2 ) const;
++	virtual int GetLen1() const { return nCnt1; }
++	virtual int GetLen2() const { return nCnt2; }
++	int GetCharSequence( const int *pWordLcs1, const int *pWordLcs2, 
++						int *pSubseq1, int *pSubseq2, int nLcsLen );
++};
++
++class CharArrayComparator : public ArrayComparator
++{
++private:
++	const SwTxtNode *pTxtNd1, *pTxtNd2;
++
++public:
++	CharArrayComparator( const SwTxtNode *pNode1, const SwTxtNode *pNode2 )
++		: pTxtNd1( pNode1 ), pTxtNd2( pNode2 )
++	{
++	}
++
++	virtual bool Compare( int nIdx1, int nIdx2 ) const;
++	virtual int GetLen1() const { return pTxtNd1->GetTxt().Len(); }
++	virtual int GetLen2() const { return pTxtNd2->GetTxt().Len(); }
++};
++
++// Options set in Tools->Options->Writer->Comparison
++struct CmpOptionsContainer
++{
++	SvxCompareMode eCmpMode;
++	int nIgnoreLen;
++	bool bUseRsid;
++} CmpOptions;
++
++class CommonSubseq
++{
++private:
++	int *pData;
++	int nSize;
++
++protected:
++	ArrayComparator &rCmp;
++
++	CommonSubseq( ArrayComparator &rComparator, int nMaxSize )
++		: nSize( nMaxSize ), rCmp( rComparator )
++	{
++		pData = new int[ nSize ];
++	}
++
++	~CommonSubseq()
++	{
++		delete[] pData;
++	}
++
++	int FindLCS( int *pLcs1 = 0, int *pLcs2 = 0, int nStt1 = 0, 
++					int nEnd1 = 0, int nStt2 = 0, int nEnd2 = 0 );
++
++public:	
++	int IgnoreIsolatedPieces( int *pLcs1, int *pLcs2, int nLen1, int nLen2, 
++								int nLcsLen, int nPieceLen );
++};
++
++// Use Hirschberg's algrithm to find LCS in linear space
++class LgstCommonSubseq: public CommonSubseq
++{
++private:
++	static const int CUTOFF = 1<<20; // Stop recursion at this value
++
++	int *pL1, *pL2;
++	int *pBuff1, *pBuff2;
++
++	void FindL( int *pL, int nStt1, int nEnd1, int nStt2, int nEnd2  );
++	int HirschbergLCS( int *pLcs1, int *pLcs2, int nStt1, int nEnd1,
++												int nStt2, int nEnd2 );
++	
++public:
++	LgstCommonSubseq( ArrayComparator &rComparator );
++	~LgstCommonSubseq();
++		
++	int Find( int *pSubseq1, int *pSubseq2 );
++};
++
++// Find a common subsequence in linear time
++class FastCommonSubseq: private CommonSubseq
++{
++private:
++	static const int CUTOFF = 2056;
++
++	int FindFastCS( int *pSeq1, int *pSeq2, int nStt1, int nEnd1,
++											 int nStt2, int nEnd2  );
++
++public:
++	FastCommonSubseq( ArrayComparator &rComparator )
++		: CommonSubseq( rComparator, CUTOFF )
++	{
++	}
++	
++	int Find( int *pSubseq1, int *pSubseq2 )
++	{
++		return FindFastCS( pSubseq1, pSubseq2, 0, rCmp.GetLen1(),
++												0, rCmp.GetLen2() );
++	}	
++};
++
+ // ====================================================================
+ 
+ CompareLine::~CompareLine() {}
+@@ -262,24 +410,21 @@ ULONG CompareData::ShowDiffs( const CompareData& rData )
+     {
+         if( rData.GetChanged( nStt1 ) || GetChanged( nStt2 ) )
+         {
++			// Find a region of different lines between two pairs of identical 
++			// lines.
+             ULONG nSav1 = nStt1, nSav2 = nStt2;
+             while( nStt1 < nLen1 && rData.GetChanged( nStt1 )) ++nStt1;
+             while( nStt2 < nLen2 && GetChanged( nStt2 )) ++nStt2;
+ 
+-            // rData ist das Original,
+-            // this ist das, in das die Veraenderungen sollen
+-            if( nSav2 != nStt2 && nSav1 != nStt1 )
+-                CheckForChangesInLine( rData, nSav1, nStt1, nSav2, nStt2 );
+-
+-            if( nSav2 != nStt2 )
+-                ShowInsert( nSav2, nStt2 );
+-
+-            if( nSav1 != nStt1 )
+-                ShowDelete( rData, nSav1, nStt1, nStt2 );
+-            ++nCnt;
++			// Check if there are changed lines (only slightly different) and
++			// compare them in detail.
++			CheckForChangesInLine( rData, nSav1, nStt1, nSav2, nStt2 );
++				
++			nCnt++;
+         }
+         ++nStt1, ++nStt2;
+     }
++
+     return nCnt;
+ }
+ 
+@@ -450,8 +595,6 @@ Compare::Compare( ULONG nDiff, CompareData& rData1, CompareData& rData2 )
+     delete pMD2;
+ }
+ 
+-
+-
+ void Compare::CountDifference( const CompareData& rData, ULONG* pCounts )
+ {
+     ULONG nLen = rData.GetLineCount();
+@@ -623,7 +766,7 @@ Compare::MovedData::~MovedData()
+     delete pIndex;
+     delete pLineNum;
+ }
+-
++ 
+ // ----------------------------------------------------------------------
+ 
+     // Suche die verschobenen Lines
+@@ -979,7 +1122,8 @@ BOOL SwCompareLine::CompareNode( const SwNode& rDstNd, const SwNode& rSrcNd )
+     switch( rDstNd.GetNodeType() )
+     {
+     case ND_TEXTNODE:
+-        bRet = CompareTxtNd( (SwTxtNode&)rDstNd, (SwTxtNode&)rSrcNd );
++		bRet = CompareTxtNd( (SwTxtNode&)rDstNd, (SwTxtNode&)rSrcNd ) 
++			&& ( !CmpOptions.bUseRsid || ((SwTxtNode&)rDstNd).CompareParRsid( (SwTxtNode&)rSrcNd ) );
+         break;
+ 
+     case ND_TABLENODE:
+@@ -1131,6 +1275,7 @@ BOOL SwCompareLine::CompareTxtNd( const SwTxtNode& rDstNd,
+                                   const SwTxtNode& rSrcNd )
+ {
+     BOOL bRet = FALSE;
++
+     // erstmal ganz einfach!
+     if( rDstNd.GetTxt() == rSrcNd.GetTxt() )
+     {
+@@ -1143,69 +1288,127 @@ BOOL SwCompareLine::CompareTxtNd( const SwTxtNode& rDstNd,
+ 
+ BOOL SwCompareLine::ChangesInLine( const SwCompareLine& rLine,
+                             SwPaM *& rpInsRing, SwPaM*& rpDelRing ) const
+-{
++{	
+     BOOL bRet = FALSE;
++
++	// Only compare textnodes
+     if( ND_TEXTNODE == rNode.GetNodeType() &&
+         ND_TEXTNODE == rLine.GetNode().GetNodeType() )
+     {
+-        SwTxtNode& rDestNd = *(SwTxtNode*)rNode.GetTxtNode();
++		SwTxtNode& rDstNd = *(SwTxtNode*)rNode.GetTxtNode();
+         const SwTxtNode& rSrcNd = *rLine.GetNode().GetTxtNode();
++		SwDoc* pDstDoc = rDstNd.GetDoc();
++		
++		int nLcsLen = 0;
+ 
+-        xub_StrLen nDEnd = rDestNd.GetTxt().Len(), nSEnd = rSrcNd.GetTxt().Len();
+-        xub_StrLen nStt;
+-        xub_StrLen nEnd;
++		int nDstLen = rDstNd.GetTxt().Len();
++		int nSrcLen = rSrcNd.GetTxt().Len();
+ 
+-        for( nStt = 0, nEnd = Min( nDEnd, nSEnd ); nStt < nEnd; ++nStt )
+-            if( rDestNd.GetTxt().GetChar( nStt ) !=
+-                rSrcNd.GetTxt().GetChar( nStt ) )
+-                break;
++		int nMinLen = std::min( nDstLen , nSrcLen );
++		int nAvgLen = ( nDstLen + nSrcLen )/2;
++
++		int *pLcsDst = new int[ nMinLen + 1 ];
++		int *pLcsSrc = new int[ nMinLen + 1 ];
+ 
+-        while( nStt < nDEnd && nStt < nSEnd )
++		if( CmpOptions.eCmpMode == SVX_CMP_BY_WORD )
+         {
+-            --nDEnd, --nSEnd;
+-            if( rDestNd.GetTxt().GetChar( nDEnd ) !=
+-                rSrcNd.GetTxt().GetChar( nSEnd ) )
++			int *pTmpLcsDst = new int[ nMinLen + 1 ];
++			int *pTmpLcsSrc = new int[ nMinLen + 1 ];
++			
++			WordArrayComparator aCmp( &rDstNd, &rSrcNd );
++			
++			LgstCommonSubseq aSeq( aCmp );
++			
++			nLcsLen = aSeq.Find( pTmpLcsDst, pTmpLcsSrc );
++
++			if( CmpOptions.nIgnoreLen )
+             {
+-                ++nDEnd, ++nSEnd;
+-                break;
++				nLcsLen = aSeq.IgnoreIsolatedPieces( pTmpLcsDst, pTmpLcsSrc,
++												aCmp.GetLen1(), aCmp.GetLen2(),
++												nLcsLen, CmpOptions.nIgnoreLen );
+             }
+-        }
+ 
+-        if( nStt || !nDEnd || !nSEnd || nDEnd < rDestNd.GetTxt().Len() ||
+-            nSEnd < rSrcNd.GetTxt().Len() )
++			nLcsLen = aCmp.GetCharSequence( pTmpLcsDst, pTmpLcsSrc,
++											pLcsDst, pLcsSrc, nLcsLen );
++
++			delete[] pTmpLcsDst;
++			delete[] pTmpLcsSrc;
++		}
++		else
++		{
++			CharArrayComparator aCmp( &rDstNd, &rSrcNd );
++			LgstCommonSubseq aSeq( aCmp );
++			
++			nLcsLen = aSeq.Find( pLcsDst, pLcsSrc );
++			
++			if( CmpOptions.nIgnoreLen )
++			{
++				nLcsLen = aSeq.IgnoreIsolatedPieces( pLcsDst, pLcsSrc, nDstLen, 
++													nSrcLen, nLcsLen, 
++													CmpOptions.nIgnoreLen );
++			}
++		}
++		
++		// find the sum of the squares of the continuous substrings
++		int nSqSum = 0;
++		int nCnt = 1;
++		for( int i = 0; i < nLcsLen; i++ )
+         {
+-            // jetzt ist zwischen nStt bis nDEnd das neu eingefuegte
+-            // und zwischen nStt und nSEnd das geloeschte
+-            SwDoc* pDoc = rDestNd.GetDoc();
+-            SwPaM aPam( rDestNd, nDEnd );
+-            if( nStt != nDEnd )
++			if( i != nLcsLen - 1 && pLcsDst[i] + 1 == pLcsDst[i + 1] 
++								&& pLcsSrc[i] + 1 == pLcsSrc[i + 1] )
++			{
++				nCnt++;
++			}
++			else
+             {
++				nSqSum += nCnt*nCnt;
++				nCnt = 1;
++			}
++		}
++		
++		// Don't compare if there aren't enough similarities
++		if ( nAvgLen >= 8 && nSqSum*32 < nAvgLen*nAvgLen )
++		{
++			return FALSE;	
++		}
++		
++		// Show the differences
++		int nSkip = 0;
++		for( int i = 0; i <= nLcsLen; i++ )
++		{
++			int nDstFrom = i ? (pLcsDst[i - 1] + 1) : 0;
++			int nDstTo = ( i == nLcsLen ) ? nDstLen : pLcsDst[i];
++			int nSrcFrom = i ? (pLcsSrc[i - 1] + 1) : 0;
++			int nSrcTo = ( i == nLcsLen ) ? nSrcLen : pLcsSrc[i];	
++
++			SwPaM aPam( rDstNd, nDstTo + nSkip );
++			
++			if ( nDstFrom < nDstTo )
++			{		
+                 SwPaM* pTmp = new SwPaM( *aPam.GetPoint(), rpInsRing );
+                 if( !rpInsRing )
+                     rpInsRing = pTmp;
+-
+                 pTmp->SetMark();
+-                pTmp->GetMark()->nContent = nStt;
++				pTmp->GetMark()->nContent = nDstFrom + nSkip;
+             }
+-
+-            if( nStt != nSEnd )
++	
++			if ( nSrcFrom < nSrcTo )
+             {
+-                {
+-                    BOOL bUndo = pDoc->DoesUndo();
+-                    pDoc->DoUndo( FALSE );
+-                    SwPaM aCpyPam( rSrcNd, nStt );
+-                    aCpyPam.SetMark();
+-                    aCpyPam.GetPoint()->nContent = nSEnd;
+-                    aCpyPam.GetDoc()->Copy( aCpyPam, *aPam.GetPoint() );
+-                    pDoc->DoUndo( bUndo );
+-                }
+-
+-                SwPaM* pTmp = new SwPaM( *aPam.GetPoint(), rpDelRing );
++				BOOL bUndo = pDstDoc->DoesUndo();
++				pDstDoc->DoUndo( FALSE );
++				SwPaM aCpyPam( rSrcNd, nSrcFrom );
++				aCpyPam.SetMark();
++				aCpyPam.GetPoint()->nContent = nSrcTo;
++				aCpyPam.GetDoc()->Copy( aCpyPam, *aPam.GetPoint() );
++				pDstDoc->DoUndo( bUndo );
++		 		
++		 		SwPaM* pTmp = new SwPaM( *aPam.GetPoint(), rpDelRing );
+                 if( !rpDelRing )
+                     rpDelRing = pTmp;
+ 
+                 pTmp->SetMark();
+-                pTmp->GetMark()->nContent = nDEnd;
++				pTmp->GetMark()->nContent = nDstTo + nSkip;
++				nSkip += nSrcTo - nSrcFrom;
+ 
+                 if( rpInsRing )
+                 {
+@@ -1214,9 +1417,14 @@ BOOL SwCompareLine::ChangesInLine( const SwCompareLine& rLine,
+                         *pCorr->GetPoint() = *pTmp->GetMark();
+                 }
+             }
+-            bRet = TRUE;
+         }
++
++		delete[] pLcsDst;
++		delete[] pLcsSrc;
++		
++		bRet = TRUE;
+     }
++	
+     return bRet;
+ }
+ 
+@@ -1395,15 +1603,52 @@ void SwCompareData::CheckForChangesInLine( const CompareData& rData,
+                                     ULONG& rStt, ULONG& rEnd,
+                                     ULONG& rThisStt, ULONG& rThisEnd )
+ {
+-    while( rStt < rEnd && rThisStt < rThisEnd )
++	LineArrayComparator aCmp( (CompareData&)*this, rData, rThisStt, rThisEnd,
++																rStt, rEnd );
++	
++	int nMinLen = std::min( aCmp.GetLen1(), aCmp.GetLen2() );
++	int *pLcsDst = new int[ nMinLen ];
++	int *pLcsSrc = new int[ nMinLen ];
++
++	FastCommonSubseq subseq( aCmp );
++	int nLcsLen = subseq.Find( pLcsDst, pLcsSrc );
++	for (int i = 0; i <= nLcsLen; i++)
+     {
+-        SwCompareLine* pDstLn = (SwCompareLine*)GetLine( rThisStt );
+-        SwCompareLine* pSrcLn = (SwCompareLine*)rData.GetLine( rStt );
+-        if( !pDstLn->ChangesInLine( *pSrcLn, pInsRing, pDelRing ) )
+-            break;
+-
+-        ++rStt;
+-        ++rThisStt;
++		// Beginning of inserted lines (inclusive)
++		int nDstFrom = i ? pLcsDst[i - 1] + 1 : 0; 
++		// End of inserted lines (exclusive)
++		int nDstTo = ( i == nLcsLen ) ? aCmp.GetLen1() : pLcsDst[i];
++		// Begining of deleted lines (inclusive)
++		int nSrcFrom = i ? pLcsSrc[i - 1] + 1 : 0; 
++		// End of deleted lines (exclusive)
++		int nSrcTo = ( i == nLcsLen ) ? aCmp.GetLen2() : pLcsSrc[i]; 
++
++		if( i )
++		{
++			SwCompareLine* pDstLn = (SwCompareLine*)GetLine( rThisStt + nDstFrom - 1 );
++			SwCompareLine* pSrcLn = (SwCompareLine*)rData.GetLine( rStt + nSrcFrom - 1 );
++	
++			// Show differences in detail for lines that 
++			// were matched as only slightly different
++			if( !pDstLn->ChangesInLine( *pSrcLn, pInsRing, pDelRing ) )
++			{
++				ShowInsert( rThisStt + nDstFrom - 1, rThisStt + nDstFrom );
++				ShowDelete( rData, rStt + nSrcFrom - 1, rStt + nSrcFrom,  
++													rThisStt + nDstFrom );
++			}
++		}
++		
++		// Lines missing from source are inserted
++		if( nDstFrom != nDstTo )
++		{		
++			ShowInsert( rThisStt + nDstFrom, rThisStt + nDstTo );
++		}
++
++		// Lines missing from destination are deleted
++		if( nSrcFrom != nSrcTo )
++		{
++			ShowDelete( rData, rStt + nSrcFrom, rStt + nSrcTo, rThisStt + nDstTo );
++		}
+     }
+ }
+ 
+@@ -1530,6 +1775,29 @@ long SwDoc::CompareDoc( const SwDoc& rDoc )
+ 
+     long nRet = 0;
+ 
++	// Get comparison options
++	CmpOptions.eCmpMode = SW_MOD()->GetCompareMode();
++	if( CmpOptions.eCmpMode == SVX_CMP_AUTO )
++	{
++		if( getRsidRoot() == rDoc.getRsidRoot() )
++		{
++			CmpOptions.eCmpMode = SVX_CMP_BY_CHAR;
++			CmpOptions.bUseRsid = true;
++			CmpOptions.nIgnoreLen = 2;
++		}
++		else
++		{
++			CmpOptions.eCmpMode = SVX_CMP_BY_WORD;
++			CmpOptions.bUseRsid = false;
++			CmpOptions.nIgnoreLen = 3;
++		}
++	}
++	else
++	{
++		CmpOptions.bUseRsid = getRsidRoot() == rDoc.getRsidRoot() && SW_MOD()->IsUseRsid();	
++		CmpOptions.nIgnoreLen = SW_MOD()->IsIgnorePieces() ? SW_MOD()->GetPieceLen() : 0;
++	}
++
+     StartUndo(UNDO_EMPTY, NULL);
+     BOOL bDocWasModified = IsModified();
+     SwDoc& rSrcDoc = (SwDoc&)rDoc;
+@@ -1823,4 +2091,576 @@ long SwDoc::MergeDoc( const SwDoc& rDoc )
+     return nRet;
+ }
+ 
++// LineArrayComparator ---------------------------------------------------------
++
++LineArrayComparator::LineArrayComparator( const CompareData &rD1,
++											const CompareData &rD2, int nStt1,
++											int nEnd1, int nStt2, int nEnd2 )
++	: rData1( rD1 ), rData2( rD2 ), nFirst1( nStt1 ), nFirst2( nStt2 )
++{
++	nLen1 = nEnd1 - nStt1;
++	nLen2 = nEnd2 - nStt2;
++}
++
++bool LineArrayComparator::Compare( int nIdx1, int nIdx2 ) const
++{
++	if( nIdx1 < 0 || nIdx2 < 0 || nIdx1 >= nLen1 || nIdx2 >= nLen2 )
++	{
++		ASSERT( 0, "Index out of range!" );
++		return false;
++	}
++
++	const SwTxtNode *pTxtNd1 = ( ( SwCompareLine* )rData1.GetLine( nFirst1 + nIdx1 ) )->GetNode().GetTxtNode();
++	const SwTxtNode *pTxtNd2 = ( ( SwCompareLine* )rData2.GetLine( nFirst2 + nIdx2 ) )->GetNode().GetTxtNode();
++
++	if( !pTxtNd1 || !pTxtNd2
++		|| ( CmpOptions.bUseRsid && !pTxtNd1->CompareParRsid( *pTxtNd2 ) ) )
++	{
++		return false;
++	}
++	
++	int nPar1Len = pTxtNd1->Len();
++	int nPar2Len = pTxtNd2->Len();
++	
++	if( std::min( nPar1Len, nPar2Len ) * 3 < std::max( nPar1Len, nPar2Len ) )
++	{
++		return false;
++	}
++	
++	int nBorderLen = ( nPar1Len + nPar2Len )/16;
++	
++	if( nBorderLen < 3 )
++	{
++		nBorderLen = std::min( 3, std::min( nPar1Len, nPar2Len ) );
++	}
++	
++	std::set<unsigned> aHashes;
++	unsigned nHash = 0;
++	unsigned nMul = 251;
++	unsigned nPow = 1;
++	int i;
++	
++	for( i = 0; i < nBorderLen - 1; i++ )
++	{
++		nPow *= nMul;
++	}
++	for( i = 0; i < nBorderLen; i++ )
++	{
++		nHash = nHash*nMul + pTxtNd1->GetTxt().GetChar( i );
++	}
++	aHashes.insert( nHash );
++	for( ; i < nPar1Len; i++ )
++	{
++		nHash = nHash - nPow*pTxtNd1->GetTxt().GetChar( i - nBorderLen );
++		nHash = nHash*nMul + pTxtNd1->GetTxt().GetChar( i );
++		
++		aHashes.insert( nHash );
++	}
++	
++	nHash = 0;
++	for( i = 0; i < nBorderLen; i++ )
++	{
++		nHash = nHash*nMul + pTxtNd2->GetTxt().GetChar( i );
++	}
++
++	if( aHashes.find( nHash ) != aHashes.end() )
++	{
++		return true;
++	}
++	
++	for( ; i < nPar2Len; i++ )
++	{
++		nHash = nHash - nPow*pTxtNd2->GetTxt().GetChar( i - nBorderLen );
++		nHash = nHash*nMul + pTxtNd2->GetTxt().GetChar( i );
++		if( aHashes.find( nHash ) != aHashes.end() )
++		{
++			return true;
++		}
++	}
++	return false;
++}
++
++// CharArrayComparator ---------------------------------------------------------
++
++bool CharArrayComparator::Compare( int nIdx1, int nIdx2 ) const
++{
++	if( nIdx1 < 0 || nIdx2 < 0 || nIdx1 >= GetLen1() || nIdx2 >= GetLen2() )
++	{
++		ASSERT( 0, "Index out of range!" );
++		return false;
++	}
++
++	return ( !CmpOptions.bUseRsid 
++			|| pTxtNd1->CompareRsid(  *pTxtNd2, nIdx1 + 1, nIdx2 + 1 ) )
++			&& pTxtNd1->GetTxt().GetChar( nIdx1 ) 
++			== pTxtNd2->GetTxt().GetChar( nIdx2 );
++}
++
++// WordArrayComparator ---------------------------------------------------------
++
++WordArrayComparator::WordArrayComparator( const SwTxtNode *pNode1, 
++											const SwTxtNode *pNode2 )
++	: pTxtNd1( pNode1 ), pTxtNd2( pNode2 ), nMul( 251 )
++{
++	pPos1 = new int[ pTxtNd1->GetTxt().Len() + 1 ];
++	pPos2 = new int[ pTxtNd2->GetTxt().Len() + 1 ];
++	
++	CalcPositions( pPos1, pTxtNd1, nCnt1 );
++	CalcPositions( pPos2, pTxtNd2, nCnt2 );
++}
++
++WordArrayComparator::~WordArrayComparator() 
++{
++	delete[] pPos1;
++	delete[] pPos2;
++}
++
++bool WordArrayComparator::Compare( int nIdx1, int nIdx2 ) const
++{	
++	int nLen = pPos1[ nIdx1 + 1 ] - pPos1[ nIdx1 ];
++	if( nLen != pPos2[ nIdx2 + 1 ] - pPos2[ nIdx2 ] )
++	{
++		return false;
++	}	
++	for( int i = 0; i < nLen; i++)
++	{
++		if( pTxtNd1->GetTxt().GetChar( pPos1[ nIdx1 ] + i ) 
++			!= pTxtNd2->GetTxt().GetChar( pPos2[ nIdx2 ] + i )
++			|| ( CmpOptions.bUseRsid && !pTxtNd1->CompareRsid( *pTxtNd2, 
++								pPos1[ nIdx1 ] + i, pPos2[ nIdx2 ] + i ) ) ) 
++		{
++			return false;
++		}
++	}
++	return true;
++}
++
++int WordArrayComparator::GetCharSequence( const int *pWordLcs1, 
++			const int *pWordLcs2, int *pSubseq1, int *pSubseq2, int nLcsLen )
++{
++	int nLen = 0;
++	for( int i = 0; i < nLcsLen; i++ )
++	{	
++		// Check for hash collisions
++		if( pPos1[ pWordLcs1[i] + 1 ] - pPos1[ pWordLcs1[i] ]
++			!= pPos2[ pWordLcs2[i] + 1 ] - pPos2[ pWordLcs2[i] ] )
++		{
++			continue;
++		}
++		for( int j = 0; j < pPos1[pWordLcs1[i]+1] - pPos1[pWordLcs1[i]]; j++)
++		{
++			pSubseq1[ nLen ] = pPos1[ pWordLcs1[i] ] + j;
++			pSubseq2[ nLen ] = pPos2[ pWordLcs2[i] ] + j;
++				
++			if( pTxtNd1->GetTxt().GetChar( pPos1[ pWordLcs1[i] ] + j )
++			 != pTxtNd2->GetTxt().GetChar( pPos2[ pWordLcs2[i] ] + j ) )
++			{
++				nLen -= j;
++				break;
++			}
++			
++			nLen++;
++		}
++	}
++	return nLen; 
++}
++
++void WordArrayComparator::CalcPositions( int *pPos, const SwTxtNode *pTxtNd,
++																	 int &nCnt )
++{
++	nCnt = -1;
++	for( int i = 0; i <= pTxtNd->GetTxt().Len(); i++ )
++	{
++		if( i == 0 || i == pTxtNd->GetTxt().Len() 
++					|| !isalnum( pTxtNd->GetTxt().GetChar( i - 1 ) ) 
++					|| !isalnum( pTxtNd->GetTxt().GetChar( i ) ) )
++		{ // Begin new word
++			nCnt++;
++			pPos[ nCnt ] = i;
++		}
++	}
++}
++
++// CommonSubseq ----------------------------------------------------------------
++
++int CommonSubseq::FindLCS( int *pLcs1, int *pLcs2, int nStt1, int nEnd1, 
++													int nStt2, int nEnd2 )
++{
++	int nLen1 = nEnd1 ? nEnd1 - nStt1 : rCmp.GetLen1();
++	int nLen2 = nEnd2 ? nEnd2 - nStt2 : rCmp.GetLen2();
++
++	assert( nLen1 >= 0 );
++	assert( nLen2 >= 0 );
++	assert( ( nLen1 + 1) * ( nLen2 + 1 ) <= maxSize );
++
++	int **pLcs = new int*[ nLen1 + 1 ];
++	pLcs[ 0 ] = pData;
++
++	for( int i = 1; i < nLen1 + 1; i++ )
++		pLcs[ i ] = pLcs[ i - 1 ] + nLen2 + 1;
++
++	for( int i = 0; i <= nLen1; i++ )
++		pLcs[i][0] = 0;
++
++	for( int j = 0; j <= nLen2; j++ )
++		pLcs[0][j] = 0;
++
++	// Find lcs
++	for( int i = 1; i <= nLen1; i++ )
++	{
++		for( int j = 1; j <= nLen2; j++ )
++		{	
++			if( rCmp.Compare( nStt1 + i - 1, nStt2 + j - 1 ) )                      
++				pLcs[i][j] = pLcs[i - 1][j - 1] + 1;                           
++			else
++				pLcs[i][j] = std::max( pLcs[i][j - 1], pLcs[i - 1][j] );
++		}
++	}
++	
++	int nLcsLen = pLcs[ nLen1 ][ nLen2 ];
++
++	// Recover the lcs in the two sequences
++	if( pLcs1 && pLcs2 )
++	{
++		int nIdx1 = nLen1;
++		int nIdx2 = nLen2;
++		int nIdx = nLcsLen - 1;
++
++		while( nIdx1 > 0 && nIdx2 > 0 )
++		{                          
++			if( pLcs[ nIdx1 ][ nIdx2 ] == pLcs[ nIdx1 - 1 ][ nIdx2 ] ) 
++				nIdx1--;
++			else if( pLcs[ nIdx1 ][ nIdx2 ] == pLcs[ nIdx1 ][ nIdx2 - 1 ] ) 
++				nIdx2--;
++			else 
++			{
++				nIdx1--, nIdx2--;
++				pLcs1[ nIdx ] = nIdx1 + nStt1;
++				pLcs2[ nIdx ] = nIdx2 + nStt2;
++				nIdx--;
++			}
++		}
++	}
++
++	delete[] pLcs;
++
++	return nLcsLen;
++}
++
++int CommonSubseq::IgnoreIsolatedPieces( int *pLcs1, int *pLcs2, int nLen1, 
++										int nLen2, int nLcsLen, int nPieceLen )
++{
++	if( !nLcsLen )
++	{
++		return 0;
++	}
++
++	int nNext = 0;
++
++	// Don't ignore text at the beginning of the paragraphs
++	if( pLcs1[ 0 ] == 0 && pLcs2[ 0 ] == 0 )
++	{
++		while( nNext < nLcsLen - 1 && pLcs1[ nNext ] + 1 == pLcs1[ nNext + 1 ]
++								&& pLcs2[ nNext ] + 1 == pLcs2[ nNext + 1 ] )
++		{	
++			nNext++;
++		}
++		nNext++;
++	}
++
++	int nCnt = 1;
++
++	for( int i = nNext; i < nLcsLen; i++ )
++	{
++		if( i != nLcsLen - 1 && pLcs1[ i ] + 1 == pLcs1[ i + 1 ]
++							&& pLcs2[ i ] + 1 == pLcs2[ i + 1 ] )
++		{
++			nCnt++;
++		}
++		else
++		{
++			if( nCnt > nPieceLen
++				// Don't ignore text at the end of the paragraphs
++				|| ( i == nLcsLen - 1 
++				&& pLcs1[i] == nLen1 - 1 && pLcs2[i] == nLen2 - 1 ))
++			{
++				for( int j = i + 1 - nCnt; j <= i; j++ )
++				{
++					pLcs2[ nNext ] = pLcs2[ j ];
++					pLcs1[ nNext ] = pLcs1[ j ];
++					nNext++;
++				}
++			}
++			nCnt = 1;
++		}
++	}
++
++	return nNext;
++}
++
++// LgstCommonSubseq ------------------------------------------------------------
+ 
++LgstCommonSubseq::LgstCommonSubseq( ArrayComparator &rComparator )
++	: CommonSubseq( rComparator, CUTOFF )
++{
++	pBuff1 = new int[ rComparator.GetLen2() + 1 ];
++	pBuff2 = new int[ rComparator.GetLen2() + 1 ];
++	
++	pL1 = new int[ rComparator.GetLen2() + 1 ];
++	pL2 = new int[ rComparator.GetLen2() + 1 ];
++}
++	
++LgstCommonSubseq::~LgstCommonSubseq()
++{
++	delete[] pBuff1;
++	delete[] pBuff2;
++	
++	delete[] pL1;
++	delete[] pL2;
++}
++
++void LgstCommonSubseq::FindL( int *pL, int nStt1, int nEnd1,
++										int nStt2, int nEnd2  )
++{
++	int nLen1 = nEnd1 ? nEnd1 - nStt1 : rCmp.GetLen1();
++	int nLen2 = nEnd2 ? nEnd2 - nStt2 : rCmp.GetLen2();
++
++	int *currL = pBuff1;
++	int *prevL = pBuff2;
++
++	// Avoid memory corruption
++	if( nLen2 > rCmp.GetLen2() )
++	{
++		assert( false );
++		return;
++	} 
++
++	memset( pBuff1, 0, sizeof( *pBuff1 ) * ( nLen2 + 1 ) );
++	memset( pBuff2, 0, sizeof( *pBuff2 ) * ( nLen2 + 1 ) );
++
++	// Find lcs
++	for( int i = 1; i <= nLen1; i++ )
++	{
++		for( int j = 1; j <= nLen2; j++ )
++		{	
++			if( rCmp.Compare( nStt1 + i - 1, nStt2 + j - 1 ) )                      
++				currL[j] = prevL[j - 1] + 1;                           
++			else
++				currL[j] = std::max( currL[j - 1], prevL[j] );
++		}
++		int *tmp = currL;
++		currL = prevL;
++		prevL = tmp;
++	}
++	memcpy( pL, prevL, ( nLen2 + 1 ) * sizeof( *prevL ) );
++}
++
++int LgstCommonSubseq::HirschbergLCS( int *pLcs1, int *pLcs2, int nStt1, 
++									int nEnd1, int nStt2, int nEnd2 )
++{
++	static int nLen1;
++	static int nLen2;
++	nLen1 = nEnd1 - nStt1;
++	nLen2 = nEnd2 - nStt2;
++
++	if( ( nLen1 + 1 ) * ( nLen2 + 1 ) <= CUTOFF )
++	{
++		if( !nLen1 || !nLen2 )
++		{
++			return 0;
++		}
++		return FindLCS(pLcs1, pLcs2, nStt1, nEnd1, nStt2, nEnd2);
++	}
++
++	int nMid = nLen1/2;
++
++	FindL( pL1, nStt1, nStt1 + nMid, nStt2, nEnd2 );
++	FindL( pL2, nStt1 + nMid, nEnd1, nStt2, nEnd2 );
++	
++	int nMaxPos = 0;
++	static int nMaxVal;
++	nMaxVal = -1;
++	
++	static int i;
++	for( i = 0; i <= nLen2; i++ )
++	{
++		if( pL1[i] + ( pL2[nLen2] - pL2[i] ) > nMaxVal )
++		{
++			nMaxPos = i;
++			nMaxVal = pL1[i]+( pL2[nLen2] - pL2[i] );
++		}
++	}
++
++	int nRet = HirschbergLCS( pLcs1, pLcs2, nStt1, nStt1 + nMid,
++											nStt2, nStt2 + nMaxPos );
++	nRet += HirschbergLCS( pLcs1 + nRet, pLcs2 + nRet, nStt1 + nMid, nEnd1,
++													nStt2 + nMaxPos, nEnd2 );
++	
++	return nRet;
++}
++
++int LgstCommonSubseq::Find( int *pSubseq1, int *pSubseq2 )
++{
++	int nStt = 0;
++	int nCutEnd = 0;
++	int nEnd1 = rCmp.GetLen1();
++	int nEnd2 = rCmp.GetLen2();
++	
++	// Check for corresponding lines in the beginning of the sequences
++	while( nStt < nEnd1 && nStt < nEnd2 && rCmp.Compare( nStt, nStt ) )
++	{
++		pSubseq1[ nStt ] = nStt;
++		pSubseq2[ nStt ] = nStt;
++		nStt++;
++	}
++
++	pSubseq1 += nStt;
++	pSubseq2 += nStt;
++
++	// Check for corresponding lines in the end of the sequences
++	while( nStt < nEnd1 && nStt < nEnd2 
++						&& rCmp.Compare( nEnd1 - 1, nEnd2 - 1 ) )
++	{
++		nCutEnd++;
++		nEnd1--;
++		nEnd2--;
++	}
++	
++	int nLen = HirschbergLCS( pSubseq1, pSubseq2, nStt, nEnd1, nStt, nEnd2 );
++	
++	for( int i = 0; i < nCutEnd; i++ )
++	{
++		pSubseq1[ nLen + i ] = nEnd1 + i;
++		pSubseq2[ nLen + i ] = nEnd2 + i;
++	}
++
++	return nStt + nLen + nCutEnd;
++}
++
++// FastCommonSubseq ------------------------------------------------------------
++
++int FastCommonSubseq::FindFastCS( int *pSeq1, int *pSeq2, int nStt1, 
++									int nEnd1, int nStt2, int nEnd2  )
++{	
++	int nCutBeg = 0;
++	int nCutEnd = 0;
++
++	// Check for corresponding lines in the beginning of the sequences
++	while( nStt1 < nEnd1 && nStt2 < nEnd2 && rCmp.Compare( nStt1, nStt2 ) )
++	{
++		pSeq1[ nCutBeg ] = nStt1++;
++		pSeq2[ nCutBeg ] = nStt2++;
++		nCutBeg++;
++	}
++
++	pSeq1 += nCutBeg;
++	pSeq2 += nCutBeg;
++
++	// Check for corresponding lines in the end of the sequences
++	while( nStt1 < nEnd1 && nStt2 < nEnd2 
++						&& rCmp.Compare( nEnd1 - 1, nEnd2 - 1 ) )
++	{
++		nCutEnd++;
++		nEnd1--;
++		nEnd2--;
++	}
++
++	int nLen1 = nEnd1 - nStt1;
++	int nLen2 = nEnd2 - nStt2;
++
++	// Return if a sequence is empty
++	if( nLen1 <= 0 || nLen2 <= 0 )
++	{
++		for( int i = 0; i < nCutEnd; i++ )
++		{
++			pSeq1[ i ] = nEnd1 + i;
++			pSeq2[ i ] = nEnd2 + i;
++		}
++		return nCutBeg + nCutEnd;
++	}
++
++	// Cut to LCS for small values
++	if( nLen1 < 3 || nLen2 < 3 || ( nLen1 + 1 ) * ( nLen2 + 1 ) <= CUTOFF )
++	{
++		int nLcsLen = FindLCS( pSeq1, pSeq2, nStt1, nEnd1, nStt2, nEnd2);
++	
++		for( int i = 0; i < nCutEnd; i++ )
++		{
++			pSeq1[ nLcsLen + i ] = nEnd1 + i;
++			pSeq2[ nLcsLen + i ] = nEnd2 + i;
++		}
++		return nCutBeg + nLcsLen + nCutEnd;
++	}
++
++	int nMid1 = nLen1/2;
++	int nMid2 = nLen2/2;
++
++	int nRad;
++	int nPos1 = -1, nPos2 = -1;
++
++	// Find a point of correspondence in the middle of the sequences
++	for( nRad = 0; nRad*nRad < std::min( nMid1, nMid2 ); nRad++ )
++	{
++		// Search to the left and to the right of the middle of the first sequence
++		for( int i = nMid1 - nRad; i <= nMid1 + nRad; i++ )
++		{
++			if( rCmp.Compare( nStt1 + i, nStt2 + nMid2 - nRad ) )
++			{
++				nPos1 = nStt1 + i;
++				nPos2 = nStt2 + nMid2 - nRad;
++				break;
++			}
++			if( rCmp.Compare( nStt1 + i, nStt2 + nMid2 + nRad ) )
++			{
++				nPos1 = nStt1 + i;
++				nPos2 = nStt2 + nMid2 - nRad;
++				break;
++			} 
++		}
++		// Search to the left and to the right of the middle of the second sequence
++		for( int i = nMid2 - nRad; i <= nMid2 + nRad; i++ )
++		{
++			if( rCmp.Compare( nStt2 + nMid2 - nRad, nStt2 + i ) )
++			{
++				nPos2 = nStt2 + i;
++				nPos1 = nStt1 + nMid1 - nRad;
++				break;
++			}
++			if( rCmp.Compare( nStt2 + nMid2 - nRad, nStt2 + i ) )
++			{
++				nPos2 = nStt2 + i;
++				nPos1 = nStt1 + nMid1 - nRad;
++				break;
++			} 
++		}
++	}
++
++	// return if no point of correspondence found
++	if( nPos1 == -1 )
++	{
++		for( int i = 0; i < nCutEnd; i++ )
++		{
++			pSeq1[ i ] = nEnd1 + i;
++			pSeq2[ i ] = nEnd2 + i;
++		}
++		return nCutBeg + nCutEnd;
++	}
++
++	// Run the same on the sequences to the left of the correspondence point
++	int nLen = FindFastCS( pSeq1, pSeq2, nStt1, nPos1, nStt2, nPos2 );
++
++	pSeq1[ nLen ] = nPos1;
++	pSeq2[ nLen ] = nPos2;
++
++	// Run the same on the sequences to the right of the correspondence point
++	nLen += FindFastCS( pSeq1 + nLen + 1, pSeq2 + nLen + 1,
++						 nPos1 + 1, nEnd1, nPos2 + 1, nEnd2 ) + 1;
++
++	for( int i = 0; i < nCutEnd; i++ )
++	{
++		pSeq1[ nLen + i ] = nEnd1 + i;
++		pSeq2[ nLen + i ] = nEnd2 + i;
++	}
++
++	return nLen + nCutBeg + nCutEnd;
++}
+diff --git sw/source/core/doc/docnew.cxx sw/source/core/doc/docnew.cxx
+index 966255b..165fe2b 100644
+--- sw/source/core/doc/docnew.cxx
++++ sw/source/core/doc/docnew.cxx
+@@ -42,6 +42,7 @@
+ #include <vcl/svapp.hxx>
+ #include <vcl/virdev.hxx>
+ #include <rtl/logfile.hxx>
++#include <rtl/random.h>
+ #include <sfx2/printer.hxx>
+ #include <sfx2/docfile.hxx>
+ #include <sfx2/frame.hxx>
+@@ -473,6 +474,14 @@ SwDoc::SwDoc() :
+     }
+     // <--
+ 
++	// Initialize the session id of the current document to a random number
++	// smaller than 2^21.
++	static rtlRandomPool aPool = rtl_random_createPool();
++	rtl_random_getBytes( aPool, &nRsid, sizeof ( nRsid ) );
++	nRsid &= ( 1<<21 ) - 1;
++	nRsid++;
++	nRsidRoot = nRsid;
++	
+     ResetModified();
+ }
+ 
+diff --git sw/source/core/edit/editsh.cxx sw/source/core/edit/editsh.cxx
+index 0a033d9..b30958d 100644
+--- sw/source/core/edit/editsh.cxx
++++ sw/source/core/edit/editsh.cxx
+@@ -115,6 +115,13 @@ void SwEditShell::Insert(const String &rStr)
+                 ASSERT( FALSE, "Doc->Insert(Str) failed." )
+             }
+ 
++			GetDoc()->UpdateRsid( *_pStartCrsr, rStr.Len() );
++			
++			// Set paragraph rsid if beginning of paragraph
++			SwTxtNode *pTxtNode = _pStartCrsr->GetPoint()->nNode.GetNode().GetTxtNode();
++			if( pTxtNode && pTxtNode->Len() == 1)
++				GetDoc()->UpdateParRsid( pTxtNode );
++
+             SaveTblBoxCntnt( _pStartCrsr->GetPoint() );
+ 
+         } while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr );
+@@ -197,7 +204,7 @@ long SwEditShell::SplitNode( BOOL bAutoFormat, BOOL bCheckTableStart )
+     StartAllAction();
+     GetDoc()->StartUndo(UNDO_EMPTY, NULL);
+ 
+-    FOREACHPAM_START(this)
++	FOREACHPAM_START(this)		
+         // eine Tabellen Zelle wird jetzt zu einer normalen Textzelle!
+         GetDoc()->ClearBoxNumAttrs( PCURCRSR->GetPoint()->nNode );
+         GetDoc()->SplitNode( *PCURCRSR->GetPoint(), bCheckTableStart );
+diff --git sw/source/core/frmedt/fecopy.cxx sw/source/core/frmedt/fecopy.cxx
+index aa5dce2..3fd117e 100644
+--- sw/source/core/frmedt/fecopy.cxx
++++ sw/source/core/frmedt/fecopy.cxx
+@@ -1059,11 +1059,12 @@ BOOL SwFEShell::Paste( SwDoc* pClpDoc, BOOL bIncludingPageFrames )
+                 // es wird mehr als 1 Node in die akt. Box kopiert. Dann
+                 // muessen die BoxAttribute aber entfernt werden.
+                 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
+-            }
++			}			
++			
+             //find out if the clipboard document starts with a table
+             bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
+             SwPosition aInsertPosition( rInsPos );
+-
++			
+             {
+                 SwNodeIndex aIndexBefore(rInsPos.nNode);
+ 
+@@ -1080,6 +1081,22 @@ BOOL SwFEShell::Paste( SwDoc* pClpDoc, BOOL bIncludingPageFrames )
+                 }
+             }
+ 
++			// Update the rsid of each pasted text node.
++			{
++				xub_StrLen nNodesCnt = aCpyPam.End()->nNode.GetIndex() - aCpyPam.Start()->nNode.GetIndex();
++				SwNodes &rDestNodes = GetDoc()->GetNodes();		
++				xub_StrLen nDestStart = PCURCRSR->GetPoint()->nNode.GetIndex() - nNodesCnt;
++									
++				for ( ULONG nIdx = 0; nIdx <= nNodesCnt; nIdx++ )
++				{
++					SwTxtNode *pTxtNode = rDestNodes[ nDestStart + nIdx ]->GetTxtNode();
++					if ( pTxtNode )
++					{
++						GetDoc()->UpdateParRsid( pTxtNode );
++					}
++				}
++			}						
++			
+             SaveTblBoxCntnt( &rInsPos );
+             if(bIncludingPageFrames && bStartWithTable)
+             {
+diff --git sw/source/core/text/atrstck.cxx sw/source/core/text/atrstck.cxx
+index ff3009c..3b4ce82 100644
+--- sw/source/core/text/atrstck.cxx
++++ sw/source/core/text/atrstck.cxx
+@@ -130,8 +130,8 @@ const BYTE StackPos[ static_cast<USHORT>(RES_TXTATR_WITHEND_END) -
+     33, // RES_CHRATR_RELIEF,                    // 36
+     34, // RES_CHRATR_HIDDEN,                    // 37
+     35, // RES_CHRATR_OVERLINE,                  // 38
+-     0, // RES_CHRATR_DUMMY1,                    // 39
+-     0, // RES_CHRATR_DUMMY2,                    // 40
++     0, // RES_CHRATR_RSID,                      // 39
++     0, // RES_DUMMY1,                           // 40
+      0, // RES_TXTATR_AUTOFMT,                   // 41
+      0, // RES_TXTATR_INETFMT                    // 42
+     36, // RES_TXTATR_REFMARK,                   // 43
+diff --git sw/source/core/txtnode/ndtxt.cxx sw/source/core/txtnode/ndtxt.cxx
+index 8730a52..2bf017e 100644
+--- sw/source/core/txtnode/ndtxt.cxx
++++ sw/source/core/txtnode/ndtxt.cxx
+@@ -40,6 +40,7 @@
+ #include <svx/brkitem.hxx>
+ #include <svx/escpitem.hxx>
+ #include <svx/lrspitem.hxx>
++#include <svx/rsiditem.hxx>
+ // --> OD 2008-01-17 #newlistlevelattrs#
+ #include <svx/tstpitem.hxx>
+ // <--
+@@ -4842,4 +4843,42 @@ USHORT SwTxtNode::ResetAllAttr()
+ 
+     return nRet;
+ }
+-// <--
++
++UINT32 SwTxtNode::GetRsid( xub_StrLen nStt, xub_StrLen nEnd ) const
++{	
++	SfxItemSet aSet( (SfxItemPool&) (GetDoc()->GetAttrPool()), RES_CHRATR_RSID, RES_CHRATR_RSID );		
++	if ( GetAttr(aSet, nStt, nEnd) )
++	{
++		SvxRsidItem* pRsid = (SvxRsidItem*)aSet.GetItem(RES_CHRATR_RSID);
++		if( pRsid )
++			return pRsid->GetValue();
++	}
++	
++	return 0;
++}
++
++UINT32 SwTxtNode::GetParRsid() const
++{	
++	SvxRsidItem &rItem = ( SvxRsidItem& ) GetAttr( RES_PARATR_RSID );
++
++	return rItem.GetValue();
++}
++
++bool SwTxtNode::CompareParRsid( const SwTxtNode &rTxtNode ) const
++{	
++	UINT32 nThisRsid = GetParRsid();
++	UINT32 nRsid = rTxtNode.GetParRsid();
++
++	return nThisRsid == nRsid;
++}
++	
++bool SwTxtNode::CompareRsid( const SwTxtNode &rTxtNode, xub_StrLen nStt1, xub_StrLen nStt2, 
++							xub_StrLen nEnd1,  xub_StrLen nEnd2 ) const
++
++{
++	UINT32 nThisRsid = GetRsid( nStt1, nEnd1 ? nEnd1 : nStt1 );
++	UINT32 nRsid = rTxtNode.GetRsid( nStt2, nEnd2 ? nEnd2 : nStt2 );
++
++	return nThisRsid == nRsid;
++}
++
+diff --git sw/source/core/undo/unspnd.cxx sw/source/core/undo/unspnd.cxx
+index af6dc8b..81b46b2 100644
+--- sw/source/core/undo/unspnd.cxx
++++ sw/source/core/undo/unspnd.cxx
+@@ -76,6 +76,8 @@ SwUndoSplitNode::SwUndoSplitNode( SwDoc* pDoc, const SwPosition& rPos,
+         pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT, pDoc->GetRedlineAuthor() );
+         SetRedlineMode( pDoc->GetRedlineMode() );
+     }
++	
++	nParRsid = pTxtNd->GetParRsid();
+ }
+ 
+ 
+@@ -157,6 +159,8 @@ void SwUndoSplitNode::Undo( SwUndoIter& rUndoIter )
+                 pDoc->RstTxtAttrs( rPam, TRUE );
+                 pHistory->TmpRollback( pDoc, 0, FALSE );
+             }
++			
++			pDoc->UpdateParRsid( pTNd, nParRsid );
+         }
+     }
+ 
+diff --git sw/source/core/unocore/unomap.cxx sw/source/core/unocore/unomap.cxx
+index 7956810..d3d7d84 100644
+--- sw/source/core/unocore/unomap.cxx
++++ sw/source/core/unocore/unomap.cxx
+@@ -216,6 +216,7 @@ void SwUnoPropertyMapProvider::Sort( sal_uInt16 nId )
+     { SW_PROP_NMID(UNO_NAME_CHAR_FONT_CHAR_SET), RES_CHRATR_FONT,		CPPU_E2T(CPPUTYPE_INT16),	PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },                    \
+     { SW_PROP_NMID(UNO_NAME_CHAR_FONT_PITCH), RES_CHRATR_FONT,		CPPU_E2T(CPPUTYPE_INT16),					PropertyAttribute::MAYBEVOID, MID_FONT_PITCH   },     \
+     { SW_PROP_NMID(UNO_NAME_CHAR_POSTURE), RES_CHRATR_POSTURE   ,  CPPU_E2T(CPPUTYPE_FONTSLANT),  		PropertyAttribute::MAYBEVOID, MID_POSTURE},                   \
++	{ SW_PROP_NMID(UNO_NAME_RSID), RES_CHRATR_RSID, CPPU_E2T(CPPUTYPE_INT32), PropertyAttribute::MAYBEVOID, 0 }, \
+     { SW_PROP_NMID(UNO_NAME_CHAR_LOCALE), RES_CHRATR_LANGUAGE ,   CPPU_E2T(CPPUTYPE_LOCALE)  ,  		PropertyAttribute::MAYBEVOID,  MID_LANG_LOCALE },
+ 
+ #define _CJK_FONT_PROPERTIES \
+@@ -289,6 +290,7 @@ void SwUnoPropertyMapProvider::Sort( sal_uInt16 nId )
+ // UNO_NAME_BREAK_TYPE and UNO_NAME_PAGE_DESC_NAME which can not be used
+ // by the SwXTextTableCursor
+ #define COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN_01 \
++		{ SW_PROP_NMID(UNO_NAME_PARRSID), RES_PARATR_RSID, CPPU_E2T(CPPUTYPE_INT32), PropertyAttribute::MAYBEVOID, 0 }, \
+         { SW_PROP_NMID(UNO_NAME_PARA_IS_HYPHENATION), RES_PARATR_HYPHENZONE,        CPPU_E2T(CPPUTYPE_BOOLEAN),     PropertyAttribute::MAYBEVOID, MID_IS_HYPHEN         },                                        \
+         { SW_PROP_NMID(UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS), RES_PARATR_HYPHENZONE,         CPPU_E2T(CPPUTYPE_INT16),   PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_LEAD   },                              \
+         { SW_PROP_NMID(UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS), RES_PARATR_HYPHENZONE,        CPPU_E2T(CPPUTYPE_INT16),   PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL  },                              \
+diff --git sw/source/core/unocore/unoprnms.cxx sw/source/core/unocore/unoprnms.cxx
+index b59ec8c..a657d96 100644
+--- sw/source/core/unocore/unoprnms.cxx
++++ sw/source/core/unocore/unoprnms.cxx
+@@ -781,6 +781,8 @@ const SwPropNameTab aPropNameTab = {
+ /* 0736 UNO_NAME_OUTLINE_LEVEL */       {MAP_CHAR_LEN("OutlineLevel")},//#outline level,add<-zhaojianwei Outlinelevel
+ /* 0737 UNO_NAME_IS_TEMPLATE */       {MAP_CHAR_LEN("IsTemplate")},
+ /* 0738 UNO_NAME_VBA_DOCOBJ */       {MAP_CHAR_LEN("ThisVBADocObj")},
++/* 0739 UNO_NAME_RSID */	{MAP_CHAR_LEN("Rsid")},
++/* 0740 UNO_NAME_PARRSID */	{MAP_CHAR_LEN("ParRsid")},
+ };
+ 
+ const SwPropNameLen& SwGetPropName( USHORT nId )
+diff --git sw/source/filter/ascii/parasc.cxx sw/source/filter/ascii/parasc.cxx
+index 96d23ea..5e4722f 100644
+--- sw/source/filter/ascii/parasc.cxx
++++ sw/source/filter/ascii/parasc.cxx
+@@ -529,6 +529,9 @@ ULONG SwASCIIParser::ReadChars()
+ void SwASCIIParser::InsertText( const String& rStr )
+ {
+     pDoc->Insert( *pPam, rStr, true );
++	pDoc->UpdateRsid( *pPam, rStr.Len() );
++	pDoc->UpdateParRsid( pPam->GetPoint()->nNode.GetNode().GetTxtNode() );
++	
+     if( pItemSet && pBreakIt && nScript != ( SCRIPTTYPE_LATIN |
+                                              SCRIPTTYPE_ASIAN |
+                                              SCRIPTTYPE_COMPLEX ) )
+diff --git sw/source/filter/html/css1atr.cxx sw/source/filter/html/css1atr.cxx
+index 0a6865d..2a6998f 100644
+--- sw/source/filter/html/css1atr.cxx
++++ sw/source/filter/html/css1atr.cxx
+@@ -3752,8 +3752,8 @@ SwAttrFnTab aCSS1AttrFnTab = {
+ /* RES_CHRATR_RELIEF */             0,
+ /* RES_CHRATR_HIDDEN */             0,
+ /* RES_CHRATR_OVERLINE */           OutCSS1_SvxOverline,
++/* RES_CHRATR_RSID */               0,
+ /* RES_CHRATR_DUMMY1 */             0,
+-/* RES_CHRATR_DUMMY2 */             0,
+ 
+ /* RES_TXTATR_NOLINEBREAK	*/      0,
+ /* RES_TXTATR_NOHYPHEN	*/			0,
+@@ -3791,6 +3791,7 @@ SwAttrFnTab aCSS1AttrFnTab = {
+ /* RES_PARATR_SNAPTOGRID*/          0, // new
+ /* RES_PARATR_CONNECT_TO_BORDER */  0, // new
+ /* RES_PARATR_OUTLINELEVEL */       0, // new since cws outlinelevel
++/* RES_PARATR_RSID */               0, // new
+ 
+ /* RES_PARATR_LIST_ID */            0, // new
+ /* RES_PARATR_LIST_LEVEL */         0, // new
+diff --git sw/source/filter/html/htmlatr.cxx sw/source/filter/html/htmlatr.cxx
+index 38c48b2..81b7329 100644
+--- sw/source/filter/html/htmlatr.cxx
++++ sw/source/filter/html/htmlatr.cxx
+@@ -3398,8 +3398,8 @@ SwAttrFnTab aHTMLAttrFnTab = {
+ /* RES_CHRATR_RELIEF */             0,
+ /* RES_CHRATR_HIDDEN */             0,
+ /* RES_CHRATR_OVERLINE */           OutHTML_CSS1Attr,
++/* RES_CHRATR_RSID */               0,
+ /* RES_CHRATR_DUMMY1 */             0,
+-/* RES_CHRATR_DUMMY2 */             0,
+ 
+ /* RES_TXTATR_DUMMY4    */          0,
+ /* RES_TXTATR_INETFMT   */          OutHTML_SwFmtINetFmt,
+diff --git sw/source/filter/rtf/rtfatr.cxx sw/source/filter/rtf/rtfatr.cxx
+index e1191cb..99b9e65 100644
+--- sw/source/filter/rtf/rtfatr.cxx
++++ sw/source/filter/rtf/rtfatr.cxx
+@@ -4232,8 +4232,8 @@ SwAttrFnTab aRTFAttrFnTab = {
+ /* RES_CHRATR_RELIEF */				OutRTF_SwCharRelief,
+ /* RES_CHRATR_HIDDEN */             OutRTF_SvxCharHiddenItem,
+ /* RES_CHRATR_OVERLINE */           OutRTF_SwOverline,
++/* RES_CHRATR_RSID */               0,
+ /* RES_CHRATR_DUMMY1 */             0,
+-/* RES_CHRATR_DUMMY2 */             0,
+ 
+ /* RES_TXTATR_AUTOFMT   */          OutRTF_SwTxtAutoFmt,
+ /* RES_TXTATR_INETFMT   */          OutRTF_SwTxtINetFmt, // Dummy
+@@ -4271,6 +4271,7 @@ SwAttrFnTab aRTFAttrFnTab = {
+ /* RES_PARATR_SNAPTOGRID*/          0, // new
+ /* RES_PARATR_CONNECT_TO_BORDER */  0, // new
+ /* RES_PARATR_OUTLINELEVEL */       0, // new - outlinelevel
++/* RES_PARATR_RSID */               0, // new
+ 
+ /* RES_PARATR_LIST_ID */            0, // new
+ /* RES_PARATR_LIST_LEVEL */         0, // new
+diff --git sw/source/filter/ww8/ww8atr.cxx sw/source/filter/ww8/ww8atr.cxx
+index 0f5b576..63f0bd4 100644
+--- sw/source/filter/ww8/ww8atr.cxx
++++ sw/source/filter/ww8/ww8atr.cxx
+@@ -5064,8 +5064,8 @@ SwAttrFnTab aWW8AttrFnTab = {
+ /* RES_CHRATR_RELIEF*/              OutWW8_Relief,
+ /* RES_CHRATR_HIDDEN */             OutWW8_SvxCharHidden,
+ /* RES_CHRATR_OVERLINE */           0,
++/* RES_CHRATR_RSID */               0,
+ /* RES_CHRATR_DUMMY1 */             0,
+-/* RES_CHRATR_DUMMY2 */             0,
+ 
+ /* RES_TXTATR_DUMMY4 */             0,
+ /* RES_TXTATR_INETFMT */            OutSwFmtINetFmt,
+@@ -5103,6 +5103,7 @@ SwAttrFnTab aWW8AttrFnTab = {
+ /* RES_PARATR_SNAPTOGRID*/          OutWW8_SvxParaGridItem,
+ /* RES_PARATR_CONNECT_TO_BORDER */  0, // new
+ /* RES_PARATR_OUTLINELEVEL */       0, // new - outlinelevel
++/* RES_PARATR_RSID */               0, // new
+ 
+ /* RES_PARATR_LIST_ID */            0, // new
+ /* RES_PARATR_LIST_LEVEL */         0, // new
+diff --git sw/source/ui/app/appopt.cxx sw/source/ui/app/appopt.cxx
+index c9774b5..dafc229 100644
+--- sw/source/ui/app/appopt.cxx
++++ sw/source/ui/app/appopt.cxx
+@@ -600,6 +600,7 @@ SfxTabPage* SwModule::CreateTabPage( USHORT nId, Window* pParent, const SfxItemS
+         case RID_SW_TP_OPTSHDWCRSR:
+         case RID_SW_TP_HTML_OPTSHDWCRSR:
+         case RID_SW_TP_REDLINE_OPT:
++        case RID_SW_TP_COMPARISON_OPT:
+         case RID_SW_TP_OPTLOAD_PAGE:
+         case RID_SW_TP_OPTCOMPATIBILITY_PAGE:
+         case RID_SW_TP_MAILCONFIG:
+diff --git sw/source/ui/app/docsh.cxx sw/source/ui/app/docsh.cxx
+index dd2f32d..28128ab 100644
+--- sw/source/ui/app/docsh.cxx
++++ sw/source/ui/app/docsh.cxx
+@@ -567,6 +567,9 @@ sal_Bool SwDocShell::SaveAs( SfxMedium& rMedium )
+         pDoc->SetOle2Link( aOldOLELnk );
+ 
+         SW_MOD()->SetEmbeddedLoadSave( FALSE );
++		
++		// Increase RSID
++		pDoc->setRsid( pDoc->getRsid() );
+     }
+     SetError( nErr ? nErr : nVBWarning );
+ 
+diff --git sw/source/ui/app/swmodul1.cxx sw/source/ui/app/swmodul1.cxx
+index ad46d70..917b829 100644
+--- sw/source/ui/app/swmodul1.cxx
++++ sw/source/ui/app/swmodul1.cxx
+@@ -741,3 +741,43 @@ void SwModule::ApplyDefaultPageMode(sal_Bool bIsSquaredPageMode)
+         GetUsrPref(sal_False);
+     pUsrPref->SetDefaultPageMode(bIsSquaredPageMode);
+ }
++
++SvxCompareMode SwModule::GetCompareMode() const
++{
++	return pModuleConfig->GetCompareMode();
++}
++
++void SwModule::SetCompareMode( SvxCompareMode eMode )
++{
++	pModuleConfig->SetCompareMode( eMode );
++}
++
++BOOL SwModule::IsUseRsid() const	
++{
++	return pModuleConfig->IsUseRsid();
++}
++
++void SwModule::SetUseRsid( BOOL b )
++{
++	pModuleConfig->SetUseRsid( b );
++}
++
++BOOL SwModule::IsIgnorePieces() const
++{
++	return pModuleConfig->IsIgnorePieces();
++}
++
++void SwModule::SetIgnorePieces( BOOL b )
++{
++	pModuleConfig->SetIgnorePieces( b );
++}
++
++USHORT SwModule::GetPieceLen() const
++{
++	return pModuleConfig->GetPieceLen();
++}
++
++void SwModule::SetPieceLen( USHORT nLen )
++{
++	pModuleConfig->SetPieceLen( nLen );
++}
+diff --git sw/source/ui/config/modcfg.cxx sw/source/ui/config/modcfg.cxx
+index 3f004af..e87925f 100644
+--- sw/source/ui/config/modcfg.cxx
++++ sw/source/ui/config/modcfg.cxx
+@@ -1385,3 +1385,92 @@ void SwMiscConfig::Load()
+         }
+     }
+ }
++
++
++
++/* -----------------------------10.10.00 16:22--------------------------------
++
++ ---------------------------------------------------------------------------*/
++const Sequence<OUString>& SwCompareConfig::GetPropertyNames()
++{
++	static Sequence<OUString> aNames;
++	if(!aNames.getLength())
++	{
++		const int nCount = 4;
++		aNames.realloc(nCount);
++		static const char* aPropNames[] =
++		{
++			"Mode",							// 0
++			"UseRSID",						// 1
++			"IgnorePieces",				// 2
++			"IgnoreLength"					// 3
++		};
++		OUString* pNames = aNames.getArray();
++		for(int i = 0; i < nCount; i++)
++			pNames[i] = OUString::createFromAscii(aPropNames[i]);
++	}
++	return aNames;
++}
++/*-- 10.10.00 16:22:22---------------------------------------------------
++
++  -----------------------------------------------------------------------*/
++SwCompareConfig::SwCompareConfig() :
++    ConfigItem(C2U("Office.Writer/Comparison"),
++        CONFIG_MODE_DELAYED_UPDATE|CONFIG_MODE_RELEASE_TREE)
++{
++	eCmpMode = SVX_CMP_AUTO;		
++	bUseRsid = 0;		
++	bIgnorePieces = 0;	
++	nPieceLen = 1;		
++
++    Load();
++}
++/*-- 10.10.00 16:22:23---------------------------------------------------
++
++  -----------------------------------------------------------------------*/
++SwCompareConfig::~SwCompareConfig()
++{
++}
++
++void SwCompareConfig::Commit()
++{
++	const Sequence<OUString>& aNames = GetPropertyNames();
++	Sequence<Any> aValues(aNames.getLength());
++	Any* pValues = aValues.getArray();
++
++   const Type& rType = ::getBooleanCppuType();
++
++	pValues[0] <<= (sal_Int32) eCmpMode;
++	pValues[1].setValue(&bUseRsid, rType);
++	pValues[2].setValue(&bIgnorePieces, rType);
++	pValues[3] <<= (sal_Int32) nPieceLen;
++	
++	PutProperties(aNames, aValues);
++}
++
++void SwCompareConfig::Load()
++{
++	const Sequence<OUString>& aNames = GetPropertyNames();
++	Sequence<Any> aValues = GetProperties(aNames);
++	const Any* pValues = aValues.getConstArray();
++	DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed");
++	if(aValues.getLength() == aNames.getLength())
++	{
++		for(int nProp = 0; nProp < aNames.getLength(); nProp++)
++		{
++			if(pValues[nProp].hasValue())
++			{
++				sal_Int32 nVal = 0;
++				pValues[nProp] >>= nVal;
++
++				switch(nProp)
++				{
++					case 0 : eCmpMode = (SvxCompareMode) nVal; break;;
++					case 1 : bUseRsid = *(sal_Bool*)pValues[nProp].getValue(); break;
++					case 2 : bIgnorePieces = *(sal_Bool*)pValues[nProp].getValue(); break;
++					case 3 : nPieceLen = nVal; break;
++				}
++			}
++		}
++	}
++}
+diff --git sw/source/ui/config/optdlg.hrc sw/source/ui/config/optdlg.hrc
+index 0045f2b..bdc49c6 100644
+--- sw/source/ui/config/optdlg.hrc
++++ sw/source/ui/config/optdlg.hrc
+@@ -206,3 +206,11 @@
+ #define FL_CRSR_OPT                   13
+ #define FL_SEPARATOR_SHDW               14
+ 
++#define FL_CMP						141
++#define RB_AUTO						142
++#define RB_WORD						143
++#define RB_CHAR						144
++#define FL_SET						145
++#define CB_RSID						146
++#define CB_IGNORE					147
++#define NF_LEN						148
+diff --git sw/source/ui/config/optdlg.src sw/source/ui/config/optdlg.src
+index e4d8ceb..4de9318 100644
+--- sw/source/ui/config/optdlg.src
++++ sw/source/ui/config/optdlg.src
+@@ -935,3 +935,77 @@ TabPage TP_OPTSHDWCRSR
+     };
+ };
+ 
++/**************************************************************************/
++/*                                                                        */
++/* 	TabPage Comparison                                           		  */
++/*                                                                        */
++/**************************************************************************/
++TabPage TP_COMPARISON_OPT
++{
++	HelpID = HID_COMPARISON_OPT;
++	SVLook = TRUE ;
++	Hide = TRUE;
++	Size = MAP_APPFONT ( 260 , 185 );
++	FixedLine FL_CMP
++	{
++        Pos = MAP_APPFONT ( 6 , 3 ) ;
++        Size = MAP_APPFONT ( 248 , 8 ) ;
++		Text [ en-US ] = "Compare documents";
++	};
++	RadioButton RB_AUTO
++	{
++		Pos = MAP_APPFONT ( 12 , 14 ) ;
++        Size = MAP_APPFONT ( 70 , 10 ) ;
++		Text [ en-US ] = "~Auto";
++		TabStop = TRUE ;
++		Group = TRUE ;
++	};
++	RadioButton RB_WORD
++	{
++		Pos = MAP_APPFONT ( 12 , 27 ) ;
++        Size = MAP_APPFONT ( 70 , 10 ) ;
++		Text [ en-US ] = "By ~word";
++	};
++	RadioButton RB_CHAR
++	{
++		Pos = MAP_APPFONT ( 12 , 40 ) ;
++        Size = MAP_APPFONT ( 70 , 10 ) ;
++		Text [ en-US ] = "By ~character";
++	};
++	FixedLine FL_SET
++	{
++        Pos = MAP_APPFONT ( 6 , 56 ) ;
++        Size = MAP_APPFONT ( 248 , 8 ) ;
++		Text [ en-US ] = "Settings";
++	};
++	CheckBox CB_RSID
++	{
++        Pos = MAP_APPFONT ( 12 , 69 ) ;
++        Size = MAP_APPFONT ( 70 , 10 ) ;
++		Text [ en-US ] = "Use ~RSID";
++		TabStop = TRUE ;
++		Group = TRUE ;
++	};
++	CheckBox CB_IGNORE
++	{
++        Pos = MAP_APPFONT ( 12 , 82 ) ;
++        Size = MAP_APPFONT ( 70 , 10 ) ;
++		Text [ en-US ] = "Ignore ~pieces of length";
++	};
++	NumericField NF_LEN
++    {
++        Pos = MAP_APPFONT ( 100 , 80 ) ;
++        Size = MAP_APPFONT ( 25 , 12 ) ;
++        Border = TRUE ;
++        Left = TRUE ;
++        First = 1 ;
++        Minimum = 1 ;
++        Maximum = 99;
++        Repeat = TRUE ;
++        Spin = TRUE ;
++        SpinSize = 1 ;
++        StrictFormat = TRUE ;
++        TabStop = TRUE ;
++    };
++};
++
+diff --git sw/source/ui/config/optpage.cxx sw/source/ui/config/optpage.cxx
+index 054eaa1..f982abc 100644
+--- sw/source/ui/config/optpage.cxx
++++ sw/source/ui/config/optpage.cxx
+@@ -103,7 +103,7 @@
+ #include <svtools/ctloptions.hxx>
+ 
+ #include <unomid.h>
+-
++#include <svx/svxenum.hxx>
+ 
+ using namespace ::com::sun::star;
+ 
+@@ -2446,6 +2446,139 @@ void SwRedlineOptionsTabPage::InitFontStyle(SvxFontPrevWindow& rExampleWin)
+ }
+ 
+ 
++//----------------------------------------------------------
++SwCompareOptionsTabPage::SwCompareOptionsTabPage(  Window* pParent, const SfxItemSet& rSet )
++	: SfxTabPage( pParent, SW_RES( TP_COMPARISON_OPT ), rSet ),
++
++	aComparisonFL(	this, SW_RES( FL_CMP ) ),
++	aAutoRB(		this, SW_RES( RB_AUTO ) ),
++	aWordRB(		this, SW_RES( RB_WORD ) ),
++	aCharRB(		this, SW_RES( RB_CHAR ) ),
++	aSettingsFL(	this, SW_RES( FL_SET ) ),
++	aRsidCB(		this, SW_RES( CB_RSID) ),
++	aIgnoreCB(		this, SW_RES( CB_IGNORE ) ),
++	aLenNF(			this, SW_RES( NF_LEN ) )	
++{
++	FreeResource();
++	Link aLnk( LINK( this, SwCompareOptionsTabPage, ComparisonHdl ) );
++	aAutoRB.SetClickHdl( aLnk );
++	aWordRB.SetClickHdl( aLnk );
++	aCharRB.SetClickHdl( aLnk );
++	
++	aIgnoreCB.SetClickHdl( LINK( this, SwCompareOptionsTabPage, IgnoreHdl) );
++}
++
++SwCompareOptionsTabPage::~SwCompareOptionsTabPage()
++{
++}
++
++SfxTabPage* SwCompareOptionsTabPage::Create( Window* pParent, const SfxItemSet& rAttrSet )
++{
++	return new SwCompareOptionsTabPage( pParent, rAttrSet );
++}
++
++BOOL SwCompareOptionsTabPage::FillItemSet( SfxItemSet& )
++{
++	BOOL bRet = FALSE;
++	SwModuleOptions *pOpt = SW_MOD()->GetModuleConfig();
++
++	if( aAutoRB.IsChecked() != aAutoRB.GetSavedValue() ||
++		aWordRB.IsChecked() != aWordRB.GetSavedValue() ||
++		aCharRB.IsChecked() != aCharRB.GetSavedValue() )
++	{
++		SvxCompareMode eCmpMode;
++		
++		if ( aAutoRB.IsChecked() ) eCmpMode = SVX_CMP_AUTO;
++		if ( aWordRB.IsChecked() ) eCmpMode = SVX_CMP_BY_WORD;
++		if ( aCharRB.IsChecked() ) eCmpMode = SVX_CMP_BY_CHAR;
++		
++		pOpt->SetCompareMode( eCmpMode );
++		bRet = TRUE;
++	}
++	
++	if( aRsidCB.IsChecked() != aRsidCB.GetSavedValue() )
++	{
++		pOpt->SetUseRsid( aRsidCB.IsChecked() );
++		bRet = TRUE;
++	}
++	
++	if( aIgnoreCB.IsChecked() != aIgnoreCB.GetSavedValue() )
++	{
++		pOpt->SetIgnorePieces( aIgnoreCB.IsChecked() );
++		bRet = TRUE;
++	}
++	
++	if( aLenNF.IsModified() )
++	{
++		pOpt->SetPieceLen( aLenNF.GetValue() );
++		bRet = TRUE;
++	}
++
++	return bRet; 
++}
++
++void SwCompareOptionsTabPage::Reset( const SfxItemSet& )
++{
++	SwModuleOptions *pOpt = SW_MOD()->GetModuleConfig();
++
++	SvxCompareMode eCmpMode = pOpt->GetCompareMode();
++	if( eCmpMode == SVX_CMP_AUTO )
++	{
++		aAutoRB.Check();
++		aSettingsFL.Disable();
++		aRsidCB.Disable();
++		aIgnoreCB.Disable();
++		aLenNF.Disable();
++	}
++	else if( eCmpMode == SVX_CMP_BY_WORD )
++	{
++		aWordRB.Check();
++		aSettingsFL.Enable();
++		aRsidCB.Enable();
++		aIgnoreCB.Enable();
++		aLenNF.Enable();
++	}
++	else if( eCmpMode == SVX_CMP_BY_CHAR)
++	{
++		aCharRB.Check();
++		aSettingsFL.Enable();
++		aRsidCB.Enable();
++		aIgnoreCB.Enable();
++		aLenNF.Enable();
++	}
++	aAutoRB.SaveValue();
++	aWordRB.SaveValue();
++	aCharRB.SaveValue();
++
++	aRsidCB.Check( pOpt->IsUseRsid() );
++	aRsidCB.SaveValue();
++	
++	aIgnoreCB.Check( pOpt->IsIgnorePieces() );
++	aIgnoreCB.SaveValue();
++	
++	aLenNF.Enable( aIgnoreCB.IsChecked() && eCmpMode );
++	
++	aLenNF.SetValue( pOpt->GetPieceLen() );
++	aLenNF.SaveValue();
++}
++
++IMPL_LINK( SwCompareOptionsTabPage, ComparisonHdl, RadioButton*, EMPTYARG )
++{
++	bool bChecked = !aAutoRB.IsChecked();
++	aSettingsFL.Enable( bChecked );
++	aRsidCB.Enable( bChecked );
++	aIgnoreCB.Enable( bChecked );
++	aLenNF.Enable( bChecked && aIgnoreCB.IsChecked() );
++	
++	return 0;
++}
++
++IMPL_LINK( SwCompareOptionsTabPage, IgnoreHdl, CheckBox*, EMPTYARG )
++{
++	aLenNF.Enable( aIgnoreCB.IsChecked() );
++	return 0;
++}
++
+ #ifndef PRODUCT
+ /*******************************************************
+  ******************************************************/
+@@ -2597,6 +2730,8 @@ IMPL_LINK_INLINE_START( SwTestTabPage, AutoClickHdl, CheckBox *, EMPTYARG )
+     return 0;
+ }
+ IMPL_LINK_INLINE_END( SwTestTabPage, AutoClickHdl, CheckBox *, EMPTYARG )
++
++
+ #endif
+ 
+ 
+diff --git sw/source/ui/dialog/swdlgfact.cxx sw/source/ui/dialog/swdlgfact.cxx
+index b8f48b3..d6f787e 100644
+--- sw/source/ui/dialog/swdlgfact.cxx
++++ sw/source/ui/dialog/swdlgfact.cxx
+@@ -1658,6 +1658,7 @@ GlossarySetActGroup	SwAbstractDialogFactory_Impl::SetGlossaryActGroupFunc( USHOR
+     return 0;
+ }
+ 
++
+ //------------------ Factories for TabPages
+ CreateTabPage SwAbstractDialogFactory_Impl::GetTabPageCreatorFunc( USHORT nId )
+ {
+@@ -1717,6 +1718,10 @@ CreateTabPage SwAbstractDialogFactory_Impl::GetTabPageCreatorFunc( USHORT nId )
+         case RID_SW_TP_MAILCONFIG:
+             pRet = SwMailConfigPage::Create;
+         break;
++        case RID_SW_TP_COMPARISON_OPT :
++        case TP_COMPARISON_OPT :
++        	pRet = SwCompareOptionsTabPage::Create;
++        break;
+     }
+ 
+     return pRet;
+diff --git sw/source/ui/inc/optpage.hxx sw/source/ui/inc/optpage.hxx
+index 050ea9f..d41862a 100644
+--- sw/source/ui/inc/optpage.hxx
++++ sw/source/ui/inc/optpage.hxx
+@@ -58,6 +58,7 @@ class SfxPrinter;
+ class SwStdFontConfig;
+ class SwWrtShell;
+ class FontList;
++class SwCompareConfig;
+ 
+ /*-----------------31.08.96 10.09-------------------
+ 
+@@ -500,6 +501,33 @@ private:
+ 
+ };
+ #endif //PRODUCT
++
++class SwCompareOptionsTabPage : public SfxTabPage
++{
++	FixedLine aComparisonFL;	
++	RadioButton aAutoRB;
++	RadioButton aWordRB;
++	RadioButton aCharRB;
++	
++	FixedLine aSettingsFL;
++	CheckBox aRsidCB;
++	CheckBox aIgnoreCB;
++	NumericField aLenNF;
++	
++	SwCompareOptionsTabPage( Window* pParent, const SfxItemSet& rSet );
++	~SwCompareOptionsTabPage();
++
++	DECL_LINK( ComparisonHdl, RadioButton *pRB);
++	DECL_LINK( IgnoreHdl, CheckBox *pCB);
++	
++public:
++
++	static SfxTabPage*	Create( Window* pParent, const SfxItemSet& rAttrSet );
++
++	virtual	BOOL 		FillItemSet( SfxItemSet& rSet );
++	virtual	void 		Reset( const SfxItemSet& rSet );
++};
++
+ #endif
+ 
+ 
+diff --git sw/source/ui/uno/SwXDocumentSettings.cxx sw/source/ui/uno/SwXDocumentSettings.cxx
+index a65d367..eb18204 100644
+--- sw/source/ui/uno/SwXDocumentSettings.cxx
++++ sw/source/ui/uno/SwXDocumentSettings.cxx
+@@ -128,6 +128,8 @@ enum SwDocumentSettingsPropertyHandles
+     HANDLE_USE_OLD_PRINTER_METRICS,
+     HANDLE_PROTECT_FORM,
+     HANDLE_TABS_RELATIVE_TO_INDENT,
++    HANDLE_RSID,
++    HANDLE_RSID_ROOT,
+     // --> OD 2008-06-05 #i89181#
+     HANDLE_TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST
+     // <--
+@@ -182,6 +184,8 @@ MasterPropertySetInfo * lcl_createSettingsInfo()
+         { RTL_CONSTASCII_STRINGPARAM("UnxForceZeroExtLeading"), HANDLE_UNIX_FORCE_ZERO_EXT_LEADING, CPPUTYPE_BOOLEAN, 0, 0},
+         { RTL_CONSTASCII_STRINGPARAM("UseOldPrinterMetrics"), HANDLE_USE_OLD_PRINTER_METRICS, CPPUTYPE_BOOLEAN, 0, 0},
+         { RTL_CONSTASCII_STRINGPARAM("TabsRelativeToIndent"), HANDLE_TABS_RELATIVE_TO_INDENT, CPPUTYPE_BOOLEAN, 0, 0},
++        { RTL_CONSTASCII_STRINGPARAM("Rsid"), HANDLE_RSID, CPPUTYPE_INT32, 0, 0},
++        { RTL_CONSTASCII_STRINGPARAM("RsidRoot"), HANDLE_RSID_ROOT, CPPUTYPE_INT32, 0, 0},
+         { RTL_CONSTASCII_STRINGPARAM("ProtectForm"), HANDLE_PROTECT_FORM, CPPUTYPE_BOOLEAN, 0, 0},
+         // --> OD 2008-06-05 #i89181#
+         { RTL_CONSTASCII_STRINGPARAM("TabAtLeftIndentForParagraphsInList"), HANDLE_TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST, CPPUTYPE_BOOLEAN, 0, 0},
+@@ -665,6 +669,20 @@ void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInf
+             mpDoc->set(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT, bTmp);
+         }
+         break;
++        case HANDLE_RSID:
++        {
++			sal_uInt32 nTmp = 0;
++			rValue >>= nTmp;
++			mpDoc->setRsid( nTmp );
++        }
++        break;
++        case HANDLE_RSID_ROOT:
++        {
++			sal_uInt32 nTmp = 0;
++			rValue >>= nTmp;
++			mpDoc->setRsidRoot( nTmp );
++        }
++        break;
+         case HANDLE_PROTECT_FORM:
+         {
+             sal_Bool bTmp = *(sal_Bool*)rValue.getValue();
+@@ -998,6 +1016,16 @@ void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInf
+             rValue.setValue( &bTmp, ::getBooleanCppuType() );
+         }
+         break;
++        case HANDLE_RSID:
++        {
++			rValue <<= static_cast < sal_Int32 > ( mpDoc->getRsid() );
++        }
++        break;
++        case HANDLE_RSID_ROOT:
++        {
++			rValue <<= static_cast < sal_Int32 > ( mpDoc->getRsidRoot() );
++        }
++        break;
+         case HANDLE_PROTECT_FORM:
+         {
+             sal_Bool bTmp = mpDoc->get(IDocumentSettingAccess::PROTECT_FORM);
+diff --git xmloff/inc/xmloff/xmltoken.hxx xmloff/inc/xmloff/xmltoken.hxx
+index 8e4cca2..e5a7a79 100644
+--- xmloff/inc/xmloff/xmltoken.hxx
++++ xmloff/inc/xmloff/xmltoken.hxx
+@@ -1488,6 +1488,8 @@ namespace xmloff { namespace token {
+         XML_ROW_HEIGHT,
+         XML_ROW_NUMBER,
+         XML_ROWS,
++        XML_RSID,
++        XML_PARRSID,
+         XML_RUBY,
+         XML_RUBY_ALIGN,
+         XML_RUBY_BASE,
+diff --git xmloff/inc/xmloff/xmltypes.hxx xmloff/inc/xmloff/xmltypes.hxx
+index cd3e443..3d011e0 100644
+--- xmloff/inc/xmloff/xmltypes.hxx
++++ xmloff/inc/xmloff/xmltypes.hxx
+@@ -154,6 +154,7 @@
+ #define XML_TYPE_NEG_PERCENT8	 	0x00002022			// (100-x)%
+ #define XML_TYPE_NEG_PERCENT16	 	0x00002023			// (100-x)
+ #define XML_TYPE_DOUBLE_PERCENT		0x00002024			// 	50% (source is a double from 0.0 to 1.0)
++#define XML_TYPE_HEX				0x00002025			// 00544F1B
+ 
+ // special basic types
+ #define XML_TYPE_RECTANGLE_LEFT		0x00000100			// the Left member of a awt::Rectangle as a measure
+diff --git xmloff/inc/xmloff/xmluconv.hxx xmloff/inc/xmloff/xmluconv.hxx
+index 8f700ab..ac7456a 100644
+--- xmloff/inc/xmloff/xmluconv.hxx
++++ xmloff/inc/xmloff/xmluconv.hxx
+@@ -237,6 +237,14 @@ public:
+     /** convert color to string */
+     static void convertColor( ::rtl::OUStringBuffer &rBuffer,
+                               const Color& rCol );
++							  
++	/** convert string (hex) to number (sal_uInt32) */						  
++	static sal_Bool convertHex( sal_uInt32& nVal,
++                              const ::rtl::OUString& rValue );
++
++	/** convert number (sal_uInt32) to string (hex) */
++	static void convertHex( ::rtl::OUStringBuffer& rBuffer,
++							   sal_uInt32 nVal );
+ 
+     /** convert number to string */
+     static void convertNumber( ::rtl::OUStringBuffer& rBuffer,
+diff --git xmloff/source/core/xmltoken.cxx xmloff/source/core/xmltoken.cxx
+index 8d2c8d6..0852545 100644
+--- xmloff/source/core/xmltoken.cxx
++++ xmloff/source/core/xmltoken.cxx
+@@ -1496,6 +1496,8 @@ namespace xmloff { namespace token {
+         TOKEN( "row-height",                      XML_ROW_HEIGHT ),
+         TOKEN( "row-number",                      XML_ROW_NUMBER ),
+         TOKEN( "rows",                            XML_ROWS ),
++        TOKEN( "rsid",                            XML_RSID ),
++        TOKEN( "paragraph-rsid",                  XML_PARRSID ),
+         TOKEN( "ruby",                            XML_RUBY ),
+         TOKEN( "ruby-align",                      XML_RUBY_ALIGN ),
+         TOKEN( "ruby-base",                       XML_RUBY_BASE ),
+diff --git xmloff/source/core/xmluconv.cxx xmloff/source/core/xmluconv.cxx
+index 910b4fd..d044ffe 100644
+--- xmloff/source/core/xmluconv.cxx
++++ xmloff/source/core/xmluconv.cxx
+@@ -646,6 +646,34 @@ void SvXMLUnitConverter::convertColor( OUStringBuffer& rBuffer,
+     rBuffer.append( sal_Unicode( aHexTab[ nCol & 0xf ] ) );
+ }
+ 
++/** convert string (hex) to number (sal_uInt32) */
++sal_Bool SvXMLUnitConverter::convertHex( sal_uInt32& nVal,
++                                       const OUString& rValue )
++{
++    if( rValue.getLength() != 8 )
++        return sal_False;
++
++	nVal = 0;
++	for ( int i = 0; i < 8; i++ )
++	{
++		nVal = ( nVal << 4 ) 
++			| sal::static_int_cast< sal_uInt32 >( lcl_gethex( rValue[i] ) );
++	} 
++
++    return sal_True;
++}
++
++/** convert number (sal_uInt32) to string (hex) */
++void SvXMLUnitConverter::convertHex( OUStringBuffer& rBuffer,
++										sal_uInt32 nVal )
++{
++	for ( int i = 0; i < 8; i++ )
++	{
++		rBuffer.append( sal_Unicode( aHexTab[ nVal >> 28 ] ) );
++		nVal <<= 4;
++	}
++}
++
+ /** convert number to string */
+ void SvXMLUnitConverter::convertNumber( OUStringBuffer& rBuffer,
+                                         sal_Int32 nNumber )
+diff --git xmloff/source/style/prhdlfac.cxx xmloff/source/style/prhdlfac.cxx
+index 81530e1..7f8b397 100644
+--- xmloff/source/style/prhdlfac.cxx
++++ xmloff/source/style/prhdlfac.cxx
+@@ -213,6 +213,9 @@ const XMLPropertyHandler* XMLPropertyHandlerFactory::CreatePropertyHandler( sal_
+         case XML_TYPE_COLOR :
+             pPropHdl = new XMLColorPropHdl;
+             break;
++		case XML_TYPE_HEX :
++			pPropHdl = new XMLHexPropHdl;
++			break;
+         case XML_TYPE_NUMBER :
+             pPropHdl = new XMLNumberPropHdl( 4 );
+             break;
+diff --git xmloff/source/style/xmlbahdl.cxx xmloff/source/style/xmlbahdl.cxx
+index 152b1ad..f99a866 100644
+--- xmloff/source/style/xmlbahdl.cxx
++++ xmloff/source/style/xmlbahdl.cxx
+@@ -559,6 +559,48 @@ sal_Bool XMLColorPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue,
+ 
+ ///////////////////////////////////////////////////////////////////////////////
+ //
++// class XMLHexPropHdl
++//
++
++XMLHexPropHdl::~XMLHexPropHdl()
++{
++	// Nothing to do
++}
++
++sal_Bool XMLHexPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
++{
++	sal_Bool bRet = sal_False;
++	sal_uInt32 nRsid;
++
++	bRet = SvXMLUnitConverter::convertHex( nRsid, rStrImpValue );
++	rValue <<= nRsid;
++
++	return bRet;
++}
++
++sal_Bool XMLHexPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
++{
++	sal_Bool bRet = sal_False;
++	sal_uInt32 nRsid = 0;
++
++	OUStringBuffer aOut;
++	if( rValue >>= nRsid )
++	{
++		SvXMLUnitConverter::convertHex( aOut, nRsid );
++		rStrExpValue = aOut.makeStringAndClear();
++
++		bRet = sal_True;
++	}
++	else
++	{
++		bRet = sal_False;
++	}
++
++	return bRet;
++}
++
++///////////////////////////////////////////////////////////////////////////////
++//
+ // class XMLStringPropHdl
+ //
+ 
+diff --git xmloff/source/style/xmlbahdl.hxx xmloff/source/style/xmlbahdl.hxx
+index 9c4e1c3..fbbbbeb 100644
+--- xmloff/source/style/xmlbahdl.hxx
++++ xmloff/source/style/xmlbahdl.hxx
+@@ -158,6 +158,18 @@ public:
+ };
+ 
+ /**
++    PropertyHandler for the XML-data-type: XML_TYPE_HEX
++*/
++class XMLHexPropHdl : public XMLPropertyHandler
++{
++public:
++	virtual ~XMLHexPropHdl();
++
++	virtual sal_Bool importXML( const ::rtl::OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
++	virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
++};
++
++/**
+     PropertyHandler for the XML-data-type: XML_TYPE_STRING
+ */
+ class XMLStringPropHdl : public XMLPropertyHandler
+diff --git xmloff/source/text/txtprmap.cxx xmloff/source/text/txtprmap.cxx
+index e68469f..6a6e960 100644
+--- xmloff/source/text/txtprmap.cxx
++++ xmloff/source/text/txtprmap.cxx
+@@ -149,6 +149,10 @@ XMLPropertyMapEntry aXMLParaPropMap[] =
+     MT_E( "CharUnderlineHasColor",	STYLE,	TEXT_UNDERLINE_COLOR,		XML_TYPE_TEXT_UNDERLINE_HASCOLOR|MID_FLAG_MERGE_ATTRIBUTE, CTF_UNDERLINE_HASCOLOR	),
+     // RES_CHRATR_WEIGHT
+     MT_E( "CharWeight",		FO,		FONT_WEIGHT,		XML_TYPE_TEXT_WEIGHT, 0 ),
++	// RES_CHRATR_RSID
++	MT_E( "Rsid",		TEXT,		RSID,		XML_TYPE_HEX, 0 ),
++	// RES_PARATR_RSID
++	MT_E( "ParRsid",	TEXT,		PARRSID,	XML_TYPE_HEX, 0 ),
+     // RES_CHRATR_WORDLINEMODE
+     MT_E( "CharWordMode",	STYLE,	TEXT_UNDERLINE_MODE,		XML_TYPE_TEXT_LINE_MODE|MID_FLAG_MERGE_PROPERTY, 0 ),
+     MT_E( "CharWordMode",   STYLE,  TEXT_OVERLINE_MODE,     XML_TYPE_TEXT_LINE_MODE|MID_FLAG_MERGE_PROPERTY, 0 ),
+@@ -444,6 +448,10 @@ XMLPropertyMapEntry aXMLTextPropMap[] =
+     MT_E( "CharUnderlineHasColor",	STYLE,	TEXT_UNDERLINE_COLOR,		XML_TYPE_TEXT_UNDERLINE_HASCOLOR|MID_FLAG_MERGE_ATTRIBUTE, CTF_UNDERLINE_HASCOLOR	),
+     // RES_CHRATR_WEIGHT
+     MT_E( "CharWeight",		FO,		FONT_WEIGHT,		XML_TYPE_TEXT_WEIGHT, 0 ),
++	// RES_CHRATR_RSID
++	MT_E( "Rsid",		TEXT,		RSID,		XML_TYPE_HEX, 0 ),
++	// RES_PARATR_RSID
++	MT_E( "ParRsid",	TEXT,		PARRSID,	XML_TYPE_HEX, 0 ),
+     // RES_CHRATR_WORDLINEMODE
+     MT_E( "CharWordMode",	STYLE,	TEXT_UNDERLINE_MODE,		XML_TYPE_TEXT_LINE_MODE|MID_FLAG_MERGE_PROPERTY, 0 ),
+     MT_E( "CharWordMode",   STYLE,  TEXT_OVERLINE_MODE,     XML_TYPE_TEXT_LINE_MODE|MID_FLAG_MERGE_PROPERTY, 0 ),


More information about the ooo-build-commit mailing list